| author | Alan
<alan@minerva.local> 2026-05-01 21:30:04 UTC |
| committer | Alan
<alan@minerva.local> 2026-05-01 21:30:04 UTC |
| parent | 425ad6d283bc958dd940fdc702555c001cf00e72 |
| Makefile | +3 | -3 |
| bootstrap/stage1-compiler.jar | +0 | -0 |
| specs/stage1.md | +28 | -37 |
| src/com/tailrecursion/larquil/stage0/BranchPatch.java | +0 | -13 |
| src/com/tailrecursion/larquil/stage0/ByteVec.java | +0 | -47 |
| src/com/tailrecursion/larquil/stage0/ClassFile.java | +0 | -190 |
| src/com/tailrecursion/larquil/stage0/CpEntry.java | +0 | -11 |
| src/com/tailrecursion/larquil/stage0/FieldInfo.java | +0 | -13 |
| src/com/tailrecursion/larquil/stage0/MethodCode.java | +0 | -199 |
| src/com/tailrecursion/larquil/stage0/Pair.java | +0 | -11 |
| src/com/tailrecursion/larquil/stage0/Writer.java | +0 | -31 |
| stage1/backend.lql | +51 | -66 |
| stage1/classfile.lql | +1643 | -0 |
| stage1/compiler.lql | +6 | -4 |
| stage1/emit.lql | +190 | -119 |
| stage1/instructions.lql | +7 | -10 |
| test/run.sh | +1 | -5 |
diff --git a/Makefile b/Makefile index 14c3fa8..ccec321 100644 --- a/Makefile +++ b/Makefile @@ -23,10 +23,10 @@ test: build stage1-build: build rm -rf $(STAGE1_DIR) mkdir -p $(STAGE1_DIR) - for f in stage1/core.lql stage1/munge.lql stage1/emit.lql; do \ + for f in stage1/core.lql stage1/munge.lql; do \ $(JAVA) -cp $(BOOTSTRAP_DIR)/stage1-compiler.jar:$(CLASSES_DIR) com.tailrecursion.larquil.stage0.Stage1Main $$f $(STAGE1_DIR); \ done - cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(STAGE1_DIR)/compiler.lql + cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(STAGE1_DIR)/compiler.lql $(JAVA) -cp $(BOOTSTRAP_DIR)/stage1-compiler.jar:$(CLASSES_DIR) com.tailrecursion.larquil.stage0.Stage1Main $(STAGE1_DIR)/compiler.lql $(STAGE1_DIR) stage1-test: stage1-build @@ -48,7 +48,7 @@ bootstrap-artifact: stage1-self-host bootstrap-test: build rm -rf $(BOOTSTRAP_TEST_DIR) mkdir -p $(BOOTSTRAP_TEST_DIR) - cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(BOOTSTRAP_TEST_DIR)/compiler.lql + cat stage1/core.lql stage1/munge.lql stage1/forms.lql stage1/reader.lql stage1/classfile.lql stage1/emit.lql stage1/instructions.lql stage1/backend.lql stage1/compiler.lql > $(BOOTSTRAP_TEST_DIR)/compiler.lql $(JAVA) -cp $(BOOTSTRAP_DIR)/stage1-compiler.jar:$(CLASSES_DIR) com.tailrecursion.larquil.stage0.Stage1Main $(BOOTSTRAP_TEST_DIR)/compiler.lql $(BOOTSTRAP_TEST_DIR) sh test/run-stage1.sh $(BOOTSTRAP_TEST_DIR) diff --git a/bootstrap/stage1-compiler.jar b/bootstrap/stage1-compiler.jar index bc93815..c7f5c29 100644 Binary files a/bootstrap/stage1-compiler.jar and b/bootstrap/stage1-compiler.jar differ diff --git a/specs/stage1.md b/specs/stage1.md index 6465ca8..e9b1b66 100644 --- a/specs/stage1.md +++ b/specs/stage1.md @@ -100,29 +100,29 @@ Registry format: Current temporary support: -- Name: `MethodCode` - Step: byte emission and instruction lowering - Reason: lets early Stage 1 functions emit into the existing classfile writer - Replacement: Larquil-owned method/code record plus Larquil byte vector - Removal condition: Stage 1 `bytevec.lql` and method writer emit loadable methods - -- Name: `ClassFile` - Step: class assembly and constant-pool work - Reason: lets Stage 1 build classes before the constant-pool writer is ported - Replacement: Larquil-owned classfile state and constant-pool helpers - Removal condition: Stage 1 classfile writer emits loader and helper classes directly - - Name: `FunctionDef` Step: function form analysis Reason: keeps the first form-analysis port aligned with the Java compiler Replacement: Larquil-shaped list or simple record representation Removal condition: Stage 1 form analysis and instruction lowering agree on the Larquil representation -- Name: `Pair` - Step: symbol tables and association lists - Reason: association-list entries need a simple representation during early porting - Replacement: Larquil list pair representation or dedicated Larquil pair value - Removal condition: `stage1/core.lql` owns lookup and pair construction +- Name: `IFunction` + Step: runtime invocation ABI + Reason: generated function classes still implement the Java bootstrap interface + Replacement: Larquil-generated `IFunction.class` + Removal condition: the bootstrap artifact ships an equivalent generated interface + +- Name: `Symbol` + Step: reader/runtime symbol values + Reason: parsed symbols still use the Java runtime class + Replacement: Larquil-generated `Symbol.class` + Removal condition: generated `Symbol` preserves interning, `name`, equality, hash, and string conversion + +- Name: `Stage1Main` + Step: command-line launcher + Reason: Makefile/tests still need a small Java entry point to call the compiler + Replacement: Larquil-generated launcher class + Removal condition: build/test targets invoke the generated launcher without compiling Java sources - Name: CLI/file bridge Step: Stage 1 entrypoint @@ -428,13 +428,7 @@ Functions to port: Temporary Java support allowed: -- `ClassFile` -- `MethodCode` -- `FieldInfo` -- `CpEntry` -- `BranchPatch` -- `Writer` -- `ByteVec` +- none for classfile writing or method bytecode assembly Done when: @@ -443,12 +437,15 @@ Done when: ## 9. Port Constant Pool And Byte Vector +Status: done in `stage1/classfile.lql`. + Port the direct classfile writer internals. Source target: - `stage1/classfile.lql` -- `stage1/bytevec.lql` +- JDK `DataOutputStream` is used for classfile output +- JDK `ByteBuffer` is used for mutable method bytecode and branch patching Functions/data to port: @@ -642,20 +639,14 @@ Done when: --- -# Current First Chunk - -The first chunk is `stage1/emit.lql`. -It ports low-level byte emission wrappers first because they are small, stable, and close to JVM bytecode. +# Current Chunk -Current functions: +The classfile backend is now Larquil-owned: -- `emit_u1` -- `emit_aconst_null` -- `emit_areturn` -- `emit_return_void` -- `emit_pop` +- `stage1/classfile.lql` owns class records, constant-pool helpers, method records, labels, branch patching, and classfile writing +- `stage1/emit.lql` emits through those Larquil records +- the refreshed bootstrap artifact has no references to the removed Java classfile backend Next best chunk: -- expand `stage1/emit.lql` to cover the remaining `MethodCode` byte-emission helpers -- add tests that call the generated helpers against a real `MethodCode` object +- generate `IFunction.class` from Larquil classfile helpers and remove `IFunction.java` diff --git a/src/com/tailrecursion/larquil/stage0/BranchPatch.java b/src/com/tailrecursion/larquil/stage0/BranchPatch.java deleted file mode 100644 index b319ac4..0000000 --- a/src/com/tailrecursion/larquil/stage0/BranchPatch.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -final class BranchPatch { - final String label; - final int opPos; - final int patchPos; - - BranchPatch(String label, int opPos, int patchPos) { - this.label = label; - this.opPos = opPos; - this.patchPos = patchPos; - } -} diff --git a/src/com/tailrecursion/larquil/stage0/ByteVec.java b/src/com/tailrecursion/larquil/stage0/ByteVec.java deleted file mode 100644 index 21027e1..0000000 --- a/src/com/tailrecursion/larquil/stage0/ByteVec.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -final class ByteVec { - byte[] data = new byte[256]; - int len = 0; - - void add(int b) { - grow(1); - data[len] = (byte) (b & 0xff); - len = len + 1; - } - - void u2(int v) { - add(v >> 8); - add(v); - } - - void u4(int v) { - add(v >> 24); - add(v >> 16); - add(v >> 8); - add(v); - } - - void patchS2(int pos, int v) { - if (v < -32768 || v > 32767) { - throw new RuntimeException("branch offset out of range: " + v); - } - data[pos] = (byte) ((v >> 8) & 0xff); - data[pos + 1] = (byte) (v & 0xff); - } - - byte[] bytes() { - byte[] out = new byte[len]; - System.arraycopy(data, 0, out, 0, len); - return out; - } - - void grow(int n) { - if (len + n <= data.length) { - return; - } - byte[] next = new byte[data.length * 2 + n]; - System.arraycopy(data, 0, next, 0, len); - data = next; - } -} diff --git a/src/com/tailrecursion/larquil/stage0/ClassFile.java b/src/com/tailrecursion/larquil/stage0/ClassFile.java deleted file mode 100644 index 3a168b5..0000000 --- a/src/com/tailrecursion/larquil/stage0/ClassFile.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; - -final class ClassFile { - final String name; - final ArrayList<Object> cp = new ArrayList<Object>(); - final HashMap<String, Integer> cpIndex = new HashMap<String, Integer>(); - final ArrayList<Object> fields = new ArrayList<Object>(); - final ArrayList<Object> methods = new ArrayList<Object>(); - final ArrayList<Object> interfaces = new ArrayList<Object>(); - - ClassFile(String name) { - this.name = name; - cpClass(name); - cpClass("java/lang/Object"); - } - - void addInterface(String iface) { - interfaces.add(Integer.valueOf(cpClass(iface))); - } - - void addField(int access, String name, String desc) { - fields.add(new FieldInfo(access, cpUtf8(name), cpUtf8(desc))); - } - - void addMethod(MethodCode m) { - methods.add(m); - } - - int cpUtf8(String value) { - String key = "U:" + value; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int idx = cp.size() + 1; - cp.add(new CpEntry(1, value)); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - int cpClass(String cls) { - String key = "C:" + cls; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int nameIdx = cpUtf8(cls); - int idx = cp.size() + 1; - cp.add(new CpEntry(7, Integer.valueOf(nameIdx))); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - int cpLong(long value) { - String key = "J:" + value; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int idx = cp.size() + 1; - cp.add(new CpEntry(5, Long.valueOf(value))); - cp.add(null); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - int cpString(String value) { - String key = "S:" + value; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int utf8Index = cpUtf8(value); - int idx = cp.size() + 1; - cp.add(new CpEntry(8, Integer.valueOf(utf8Index))); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - int cpNameType(String name, String desc) { - String key = "NT:" + name + ":" + desc; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int nameIndex = cpUtf8(name); - int descIndex = cpUtf8(desc); - int idx = cp.size() + 1; - cp.add(new CpEntry(12, new int[]{nameIndex, descIndex})); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - int cpFieldref(String cls, String name, String desc) { - return cpRef(9, "F:", cls, name, desc); - } - - int cpMethodref(String cls, String name, String desc) { - return cpRef(10, "M:", cls, name, desc); - } - - int cpInterfaceMethodref(String cls, String name, String desc) { - return cpRef(11, "IM:", cls, name, desc); - } - - int cpRef(int tag, String prefix, String cls, String name, String desc) { - String key = prefix + cls + ":" + name + ":" + desc; - Integer got = cpIndex.get(key); - if (got != null) { - return got.intValue(); - } - int classIndex = cpClass(cls); - int nameTypeIndex = cpNameType(name, desc); - int idx = cp.size() + 1; - cp.add(new CpEntry(tag, new int[]{classIndex, nameTypeIndex})); - cpIndex.put(key, Integer.valueOf(idx)); - return idx; - } - - byte[] bytes() { - cpUtf8("Code"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Writer w = new Writer(out); - w.u4(0xcafebabe); - w.u2(0); - w.u2(49); - w.u2(cp.size() + 1); - int i = 0; - while (i < cp.size()) { - CpEntry e = (CpEntry) cp.get(i); - if (e != null) { - writeCp(w, e); - } - i = i + 1; - } - w.u2(0x0031); - w.u2(cpClass(name)); - w.u2(cpClass("java/lang/Object")); - w.u2(interfaces.size()); - i = 0; - while (i < interfaces.size()) { - w.u2(((Integer) interfaces.get(i)).intValue()); - i = i + 1; - } - w.u2(fields.size()); - i = 0; - while (i < fields.size()) { - FieldInfo f = (FieldInfo) fields.get(i); - w.u2(f.access); - w.u2(f.name); - w.u2(f.desc); - w.u2(0); - i = i + 1; - } - w.u2(methods.size()); - i = 0; - while (i < methods.size()) { - ((MethodCode) methods.get(i)).write(w); - i = i + 1; - } - w.u2(0); - return out.toByteArray(); - } - - void writeCp(Writer w, CpEntry e) { - w.u1(e.tag); - if (e.tag == 1) { - byte[] bytes = ((String) e.value).getBytes(StandardCharsets.UTF_8); - w.u2(bytes.length); - w.bytes(bytes); - } else if (e.tag == 7 || e.tag == 8) { - w.u2(((Integer) e.value).intValue()); - } else if (e.tag == 5) { - long v = ((Long) e.value).longValue(); - w.u4((int) (v >> 32)); - w.u4((int) v); - } else if (e.tag == 9 || e.tag == 10 || e.tag == 11 || e.tag == 12) { - int[] pair = (int[]) e.value; - w.u2(pair[0]); - w.u2(pair[1]); - } else { - throw new RuntimeException("bad cp tag: " + e.tag); - } - } -} diff --git a/src/com/tailrecursion/larquil/stage0/CpEntry.java b/src/com/tailrecursion/larquil/stage0/CpEntry.java deleted file mode 100644 index 69a5c96..0000000 --- a/src/com/tailrecursion/larquil/stage0/CpEntry.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -final class CpEntry { - final int tag; - final Object value; - - CpEntry(int tag, Object value) { - this.tag = tag; - this.value = value; - } -} diff --git a/src/com/tailrecursion/larquil/stage0/FieldInfo.java b/src/com/tailrecursion/larquil/stage0/FieldInfo.java deleted file mode 100644 index fb8e5ca..0000000 --- a/src/com/tailrecursion/larquil/stage0/FieldInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -final class FieldInfo { - final int access; - final int name; - final int desc; - - FieldInfo(int access, int name, int desc) { - this.access = access; - this.name = name; - this.desc = desc; - } -} diff --git a/src/com/tailrecursion/larquil/stage0/MethodCode.java b/src/com/tailrecursion/larquil/stage0/MethodCode.java deleted file mode 100644 index 3821138..0000000 --- a/src/com/tailrecursion/larquil/stage0/MethodCode.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -import java.util.ArrayList; - -final class MethodCode { - final ClassFile cf; - final int access; - final int nameIndex; - final int descIndex; - final ByteVec code = new ByteVec(); - final ArrayList<Object> labels = new ArrayList<Object>(); - final ArrayList<Object> patches = new ArrayList<Object>(); - int maxStack = 64; - int maxLocals = 2; - int internal = 0; - - MethodCode(ClassFile cf, int access, String name, String desc) { - this.cf = cf; - this.access = access; - this.nameIndex = cf.cpUtf8(name); - this.descIndex = cf.cpUtf8(desc); - } - - int nextInternal() { - int v = internal; - internal = internal + 1; - return v; - } - - void u1(int v) { - code.add(v); - } - - void u2(int v) { - code.u2(v); - } - - void pushInt(int v) { - if (v >= -1 && v <= 5) { - u1(0x03 + v); - } else if (v >= -128 && v <= 127) { - u1(0x10); - u1(v); - } else { - u1(0x11); - u2(v); - } - } - - void aload(int slot) { - if (slot >= 0 && slot <= 3) { - u1(0x2a + slot); - } else { - u1(0x19); - u1(slot); - } - } - - void astore(int slot) { - if (slot >= 0 && slot <= 3) { - u1(0x4b + slot); - } else { - u1(0x3a); - u1(slot); - } - } - - void lconst(long value) { - u1(0x14); - u2(cf.cpLong(value)); - invokestatic("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); - } - - void sconst(String value) { - int idx = cf.cpString(value); - if (idx <= 255) { - u1(0x12); - u1(idx); - } else { - u1(0x13); - u2(idx); - } - } - - void getstatic(String cls, String name, String desc) { - u1(0xb2); - u2(cf.cpFieldref(cls, name, desc)); - } - - void putstatic(String cls, String name, String desc) { - u1(0xb3); - u2(cf.cpFieldref(cls, name, desc)); - } - - void getfield(String cls, String name, String desc) { - u1(0xb4); - u2(cf.cpFieldref(cls, name, desc)); - } - - void putfield(String cls, String name, String desc) { - u1(0xb5); - u2(cf.cpFieldref(cls, name, desc)); - } - - void checkcast(String cls) { - u1(0xc0); - u2(cf.cpClass(cls)); - } - - void newobj(String cls) { - u1(0xbb); - u2(cf.cpClass(cls)); - } - - void anewarray(String cls) { - u1(0xbd); - u2(cf.cpClass(cls)); - } - - void invokespecial(String cls, String name, String desc) { - u1(0xb7); - u2(cf.cpMethodref(cls, name, desc)); - } - - void invokevirtual(String cls, String name, String desc) { - u1(0xb6); - u2(cf.cpMethodref(cls, name, desc)); - } - - void invokestatic(String cls, String name, String desc) { - u1(0xb8); - u2(cf.cpMethodref(cls, name, desc)); - } - - void invokeinterface(String cls, String name, String desc, int count) { - u1(0xb9); - u2(cf.cpInterfaceMethodref(cls, name, desc)); - u1(count); - u1(0); - } - - void branch(int opcode, String label) { - int opPos = code.len; - u1(opcode); - int patchPos = code.len; - u2(0); - patches.add(new BranchPatch(label, opPos, patchPos)); - } - - void label(String name) { - if (lookupLabel(name) != null) { - throw new RuntimeException("duplicate label: " + name); - } - labels.add(new Pair(Symbol.intern(name), Integer.valueOf(code.len))); - } - - Integer lookupLabel(String name) { - Symbol s = Symbol.intern(name); - int i = labels.size() - 1; - while (i >= 0) { - Pair p = (Pair) labels.get(i); - if (s.equals(p.a)) { - return (Integer) p.b; - } - i = i - 1; - } - return null; - } - - void finishLabels() { - int i = 0; - while (i < patches.size()) { - BranchPatch p = (BranchPatch) patches.get(i); - Integer target = lookupLabel(p.label); - if (target == null) { - throw new RuntimeException("unresolved label: " + p.label); - } - code.patchS2(p.patchPos, target.intValue() - p.opPos); - i = i + 1; - } - } - - void write(Writer w) { - finishLabels(); - byte[] bytes = code.bytes(); - w.u2(access); - w.u2(nameIndex); - w.u2(descIndex); - w.u2(1); - w.u2(cf.cpUtf8("Code")); - w.u4(12 + bytes.length); - w.u2(maxStack); - w.u2(maxLocals); - w.u4(bytes.length); - w.bytes(bytes); - w.u2(0); - w.u2(0); - } -} diff --git a/src/com/tailrecursion/larquil/stage0/Pair.java b/src/com/tailrecursion/larquil/stage0/Pair.java deleted file mode 100644 index f218763..0000000 --- a/src/com/tailrecursion/larquil/stage0/Pair.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -final class Pair { - final Object a; - final Object b; - - Pair(Object a, Object b) { - this.a = a; - this.b = b; - } -} diff --git a/src/com/tailrecursion/larquil/stage0/Writer.java b/src/com/tailrecursion/larquil/stage0/Writer.java deleted file mode 100644 index 35d28b1..0000000 --- a/src/com/tailrecursion/larquil/stage0/Writer.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.tailrecursion.larquil.stage0; - -import java.io.ByteArrayOutputStream; - -final class Writer { - final ByteArrayOutputStream out; - - Writer(ByteArrayOutputStream out) { - this.out = out; - } - - void u1(int v) { - out.write(v & 0xff); - } - - void u2(int v) { - u1(v >> 8); - u1(v); - } - - void u4(int v) { - u1(v >> 24); - u1(v >> 16); - u1(v >> 8); - u1(v); - } - - void bytes(byte[] bytes) { - out.write(bytes, 0, bytes.length); - } -} diff --git a/stage1/backend.lql b/stage1/backend.lql index 0397bc7..f101722 100644 --- a/stage1/backend.lql +++ b/stage1/backend.lql @@ -109,7 +109,6 @@ (checkcast "java/util/ArrayList") (iconst 0) (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (return)) (function state_env (state) @@ -143,14 +142,13 @@ (load value) (invokevirtual "java/util/ArrayList" "set" "(ILjava/lang/Object;)Ljava/lang/Object;") (pop) + (load-function method_set_max_locals) (load-function state_method) (load state) (invoke 1) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load value) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (putfield "com/tailrecursion/larquil/stage0/MethodCode" "maxLocals" "I") + (invoke 2) + (pop) (aconst-null) (return)) @@ -269,14 +267,12 @@ (return)) (function add_constructor (cf) - (new "com/tailrecursion/larquil/stage0/MethodCode") - (dup) + (load-function method_code) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 1) + (lconst 1) (sconst "<init>") (sconst "()V") - (invokespecial "com/tailrecursion/larquil/stage0/MethodCode" "<init>" "(Lcom/tailrecursion/larquil/stage0/ClassFile;ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) (store m) (load-function emit_u1) (load m) @@ -294,23 +290,20 @@ (load m) (invoke 1) (pop) + (load-function class_add_method) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addMethod" "(Lcom/tailrecursion/larquil/stage0/MethodCode;)V") + (invoke 2) (aconst-null) (return)) (function add_clinit (cf name) - (new "com/tailrecursion/larquil/stage0/MethodCode") - (dup) + (load-function method_code) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 8) + (lconst 8) (sconst "<clinit>") (sconst "()V") - (invokespecial "com/tailrecursion/larquil/stage0/MethodCode" "<init>" "(Lcom/tailrecursion/larquil/stage0/ClassFile;ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) (store m) (load-function emit_new) (load m) @@ -350,23 +343,20 @@ (load m) (invoke 1) (pop) + (load-function class_add_method) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addMethod" "(Lcom/tailrecursion/larquil/stage0/MethodCode;)V") + (invoke 2) (aconst-null) (return)) (function add_main (cf name) - (new "com/tailrecursion/larquil/stage0/MethodCode") - (dup) + (load-function method_code) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 9) + (lconst 9) (sconst "main") (sconst "([Ljava/lang/String;)V") - (invokespecial "com/tailrecursion/larquil/stage0/MethodCode" "<init>" "(Lcom/tailrecursion/larquil/stage0/ClassFile;ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) (store m) (load-function emit_getstatic) (load m) @@ -411,11 +401,10 @@ (load m) (invoke 1) (pop) + (load-function class_add_method) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addMethod" "(Lcom/tailrecursion/larquil/stage0/MethodCode;)V") + (invoke 2) (aconst-null) (return)) @@ -424,19 +413,18 @@ (load def) (invoke 1) (store class_name) - (new "com/tailrecursion/larquil/stage0/ClassFile") - (dup) + (load-function class_file) (load class_name) - (checkcast "java/lang/String") - (invokespecial "com/tailrecursion/larquil/stage0/ClassFile" "<init>" "(Ljava/lang/String;)V") + (invoke 1) (store cf) + (load-function class_add_interface) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (sconst "com/tailrecursion/larquil/stage0/IFunction") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addInterface" "(Ljava/lang/String;)V") + (invoke 2) + (pop) + (load-function class_add_field) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 25) + (lconst 25) (sconst "INSTANCE") (new "java/lang/StringBuilder") (dup) @@ -449,7 +437,8 @@ (sconst ";") (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") (invokevirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addField" "(ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) + (pop) (load-function add_constructor) (load cf) (invoke 1) @@ -457,14 +446,12 @@ (load cf) (load class_name) (invoke 2) - (new "com/tailrecursion/larquil/stage0/MethodCode") - (dup) + (load-function method_code) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 1) + (lconst 1) (sconst "invoke") (sconst "([Ljava/lang/Object;)Ljava/lang/Object;") - (invokespecial "com/tailrecursion/larquil/stage0/MethodCode" "<init>" "(Lcom/tailrecursion/larquil/stage0/ClassFile;ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) (store method) (load-function compile_state) (load method) @@ -575,14 +562,15 @@ (load method) (invoke 1) (pop) + (load-function finish_labels) (load method) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "finishLabels" "()V") + (invoke 1) + (pop) + (load-function class_add_method) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (load method) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addMethod" "(Lcom/tailrecursion/larquil/stage0/MethodCode;)V") + (invoke 2) + (pop) (load cf) (return)) @@ -609,23 +597,22 @@ (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") (invokevirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;") (store self_desc) - (new "com/tailrecursion/larquil/stage0/ClassFile") - (dup) + (load-function class_file) (load name) - (checkcast "java/lang/String") - (invokespecial "com/tailrecursion/larquil/stage0/ClassFile" "<init>" "(Ljava/lang/String;)V") + (invoke 1) (store cf) + (load-function class_add_interface) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (sconst "com/tailrecursion/larquil/stage0/IFunction") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addInterface" "(Ljava/lang/String;)V") + (invoke 2) + (pop) + (load-function class_add_field) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 25) + (lconst 25) (sconst "INSTANCE") (load self_desc) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addField" "(ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) + (pop) (load-function add_constructor) (load cf) (invoke 1) @@ -637,14 +624,12 @@ (load cf) (load name) (invoke 2) - (new "com/tailrecursion/larquil/stage0/MethodCode") - (dup) + (load-function method_code) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (iconst 1) + (lconst 1) (sconst "invoke") (sconst "([Ljava/lang/Object;)Ljava/lang/Object;") - (invokespecial "com/tailrecursion/larquil/stage0/MethodCode" "<init>" "(Lcom/tailrecursion/larquil/stage0/ClassFile;ILjava/lang/String;Ljava/lang/String;)V") + (invoke 4) (store method) (load-function emit_arity_check) (load method) @@ -725,10 +710,10 @@ (load method) (invoke 1) (pop) + (load-function class_add_method) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") (load method) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "addMethod" "(Lcom/tailrecursion/larquil/stage0/MethodCode;)V") + (invoke 2) + (pop) (load cf) (return)) diff --git a/stage1/classfile.lql b/stage1/classfile.lql new file mode 100644 index 0000000..47005da --- /dev/null +++ b/stage1/classfile.lql @@ -0,0 +1,1643 @@ +; Larquil-owned JVM classfile and method assembly. + +(function rec_get (xs idx) + (load xs) + (checkcast "java/util/ArrayList") + (load idx) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (return)) + +(function rec_set (xs idx value) + (load xs) + (checkcast "java/util/ArrayList") + (load idx) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (load value) + (invokevirtual "java/util/ArrayList" "set" "(ILjava/lang/Object;)Ljava/lang/Object;") + (pop) + (aconst-null) + (return)) + +(function rec_add (xs value) + (load xs) + (checkcast "java/util/ArrayList") + (load value) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function new_list () + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (return)) + +(function cp_entry (tag value) + (load-function pair) + (load tag) + (load value) + (invoke 2) + (return)) + +(function cp_tag (entry) + (load-function pair_a) + (load entry) + (invoke 1) + (return)) + +(function cp_value (entry) + (load-function pair_b) + (load entry) + (invoke 1) + (return)) + +(function field_info (access name desc) + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (store f) + (load-function rec_add) + (load f) + (load access) + (invoke 2) + (pop) + (load-function rec_add) + (load f) + (load name) + (invoke 2) + (pop) + (load-function rec_add) + (load f) + (load desc) + (invoke 2) + (pop) + (load f) + (return)) + +(function field_access (f) + (load-function rec_get) + (load f) + (lconst 0) + (invoke 2) + (return)) + +(function field_name (f) + (load-function rec_get) + (load f) + (lconst 1) + (invoke 2) + (return)) + +(function field_desc (f) + (load-function rec_get) + (load f) + (lconst 2) + (invoke 2) + (return)) + +(function branch_patch (label op_pos patch_pos) + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (store p) + (load-function rec_add) + (load p) + (load label) + (invoke 2) + (pop) + (load-function rec_add) + (load p) + (load op_pos) + (invoke 2) + (pop) + (load-function rec_add) + (load p) + (load patch_pos) + (invoke 2) + (pop) + (load p) + (return)) + +(function patch_label (p) + (load-function rec_get) + (load p) + (lconst 0) + (invoke 2) + (return)) + +(function patch_op_pos (p) + (load-function rec_get) + (load p) + (lconst 1) + (invoke 2) + (return)) + +(function patch_patch_pos (p) + (load-function rec_get) + (load p) + (lconst 2) + (invoke 2) + (return)) + +(function key2 (prefix a) + (new "java/lang/StringBuilder") + (dup) + (invokespecial "java/lang/StringBuilder" "<init>" "()V") + (load prefix) + (checkcast "java/lang/String") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load a) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (invokevirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;") + (return)) + +(function key4 (prefix a b c) + (new "java/lang/StringBuilder") + (dup) + (invokespecial "java/lang/StringBuilder" "<init>" "()V") + (load prefix) + (checkcast "java/lang/String") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load a) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (sconst ":") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load b) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (sconst ":") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load c) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (invokevirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;") + (return)) + +(function key3 (prefix a b) + (new "java/lang/StringBuilder") + (dup) + (invokespecial "java/lang/StringBuilder" "<init>" "()V") + (load prefix) + (checkcast "java/lang/String") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load a) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (sconst ":") + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") + (load b) + (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/Object;)Ljava/lang/StringBuilder;") + (invokevirtual "java/lang/StringBuilder" "toString" "()Ljava/lang/String;") + (return)) + +(function class_file (name) + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (store cf) + (load-function rec_add) + (load cf) + (load name) + (invoke 2) + (pop) + (load-function rec_add) + (load cf) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load cf) + (new "java/util/HashMap") + (dup) + (invokespecial "java/util/HashMap" "<init>" "()V") + (invoke 2) + (pop) + (load-function rec_add) + (load cf) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load cf) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load cf) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function cp_class) + (load cf) + (load name) + (invoke 2) + (pop) + (load-function cp_class) + (load cf) + (sconst "java/lang/Object") + (invoke 2) + (pop) + (load cf) + (return)) + +(function class_name (cf) + (load-function rec_get) + (load cf) + (lconst 0) + (invoke 2) + (checkcast "java/lang/String") + (return)) + +(function class_cp (cf) + (load-function rec_get) + (load cf) + (lconst 1) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function class_cp_index (cf) + (load-function rec_get) + (load cf) + (lconst 2) + (invoke 2) + (checkcast "java/util/HashMap") + (return)) + +(function class_fields (cf) + (load-function rec_get) + (load cf) + (lconst 3) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function class_methods (cf) + (load-function rec_get) + (load cf) + (lconst 4) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function class_interfaces (cf) + (load-function rec_get) + (load cf) + (lconst 5) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function cp_lookup (cf key) + (load-function class_cp_index) + (load cf) + (invoke 1) + (checkcast "java/util/HashMap") + (load key) + (checkcast "java/lang/String") + (invokevirtual "java/util/HashMap" "get" "(Ljava/lang/Object;)Ljava/lang/Object;") + (return)) + +(function cp_store (cf key idx) + (load-function class_cp_index) + (load cf) + (invoke 1) + (checkcast "java/util/HashMap") + (load key) + (checkcast "java/lang/String") + (load idx) + (invokevirtual "java/util/HashMap" "put" "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") + (pop) + (aconst-null) + (return)) + +(function next_cp_index (cf) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (lconst 1) + (ladd) + (return)) + +(function cp_utf8 (cf value) + (load-function key2) + (sconst "U:") + (load value) + (invoke 2) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (lconst 1) + (load value) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_class (cf cls) + (load-function key2) + (sconst "C:") + (load cls) + (invoke 2) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function cp_utf8) + (load cf) + (load cls) + (invoke 2) + (store name_idx) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (lconst 7) + (load name_idx) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_long (cf value) + (load-function key2) + (sconst "J:") + (load value) + (invoke 2) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (lconst 5) + (load value) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (aconst-null) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_string (cf value) + (load-function key2) + (sconst "S:") + (load value) + (invoke 2) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function cp_utf8) + (load cf) + (load value) + (invoke 2) + (store utf8_idx) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (lconst 8) + (load utf8_idx) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_name_type (cf name desc) + (load-function key3) + (sconst "NT:") + (load name) + (load desc) + (invoke 3) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function cp_utf8) + (load cf) + (load name) + (invoke 2) + (store name_idx) + (load-function cp_utf8) + (load cf) + (load desc) + (invoke 2) + (store desc_idx) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (lconst 12) + (load-function pair) + (load name_idx) + (load desc_idx) + (invoke 2) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_ref (cf tag prefix cls name desc) + (load-function key4) + (load prefix) + (load cls) + (load name) + (load desc) + (invoke 4) + (store key) + (load-function cp_lookup) + (load cf) + (load key) + (invoke 2) + (store got) + (load got) + (jump-if-false miss) + (load got) + (return) + (label miss) + (load-function cp_class) + (load cf) + (load cls) + (invoke 2) + (store class_idx) + (load-function cp_name_type) + (load cf) + (load name) + (load desc) + (invoke 3) + (store nt_idx) + (load-function next_cp_index) + (load cf) + (invoke 1) + (store idx) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_entry) + (load tag) + (load-function pair) + (load class_idx) + (load nt_idx) + (invoke 2) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (load-function cp_store) + (load cf) + (load key) + (load idx) + (invoke 3) + (pop) + (load idx) + (return)) + +(function cp_fieldref (cf cls name desc) + (load-function cp_ref) + (load cf) + (lconst 9) + (sconst "F:") + (load cls) + (load name) + (load desc) + (invoke 6) + (return)) + +(function cp_methodref (cf cls name desc) + (load-function cp_ref) + (load cf) + (lconst 10) + (sconst "M:") + (load cls) + (load name) + (load desc) + (invoke 6) + (return)) + +(function cp_interface_methodref (cf cls name desc) + (load-function cp_ref) + (load cf) + (lconst 11) + (sconst "IM:") + (load cls) + (load name) + (load desc) + (invoke 6) + (return)) + +(function class_add_interface (cf iface) + (load-function class_interfaces) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function cp_class) + (load cf) + (load iface) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function class_add_field (cf access name desc) + (load-function class_fields) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function field_info) + (load access) + (load-function cp_utf8) + (load cf) + (load name) + (invoke 2) + (load-function cp_utf8) + (load cf) + (load desc) + (invoke 2) + (invoke 3) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function class_add_method (cf method) + (load-function class_methods) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load method) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function writer () + (new "java/io/ByteArrayOutputStream") + (dup) + (invokespecial "java/io/ByteArrayOutputStream" "<init>" "()V") + (store out) + (new "java/io/DataOutputStream") + (dup) + (load out) + (checkcast "java/io/OutputStream") + (invokespecial "java/io/DataOutputStream" "<init>" "(Ljava/io/OutputStream;)V") + (store data) + (load-function pair) + (load out) + (load data) + (invoke 2) + (return)) + +(function writer_out (w) + (load-function pair_a) + (load w) + (invoke 1) + (checkcast "java/io/ByteArrayOutputStream") + (return)) + +(function writer_data (w) + (load-function pair_b) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (return)) + +(function write_u1 (w value) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/io/DataOutputStream" "writeByte" "(I)V") + (aconst-null) + (return)) + +(function write_u2 (w value) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/io/DataOutputStream" "writeShort" "(I)V") + (aconst-null) + (return)) + +(function write_u4 (w value) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/io/DataOutputStream" "writeInt" "(I)V") + (aconst-null) + (return)) + +(function write_long (w value) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "longValue" "()J") + (invokevirtual "java/io/DataOutputStream" "writeLong" "(J)V") + (aconst-null) + (return)) + +(function write_bytes (w bytes) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (load bytes) + (checkcast "[B") + (invokevirtual "java/io/DataOutputStream" "write" "([B)V") + (aconst-null) + (return)) + +(function byte_array_length (bytes) + (load bytes) + (invokestatic "java/lang/reflect/Array" "getLength" "(Ljava/lang/Object;)I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (return)) + +(function writer_bytes (w) + (load-function writer_data) + (load w) + (invoke 1) + (checkcast "java/io/DataOutputStream") + (invokevirtual "java/io/DataOutputStream" "flush" "()V") + (load-function writer_out) + (load w) + (invoke 1) + (checkcast "java/io/ByteArrayOutputStream") + (invokevirtual "java/io/ByteArrayOutputStream" "toByteArray" "()[B") + (return)) + +(function write_cp (w entry) + (load-function write_u1) + (load w) + (load-function cp_tag) + (load entry) + (invoke 1) + (invoke 2) + (pop) + (load-function cp_tag) + (load entry) + (invoke 1) + (store tag) + (load tag) + (lconst 1) + (invokevirtual "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") + (ifeq try_class_string) + (load-function cp_value) + (load entry) + (invoke 1) + (checkcast "java/lang/String") + (getstatic "java/nio/charset/StandardCharsets" "UTF_8" "Ljava/nio/charset/Charset;") + (invokevirtual "java/lang/String" "getBytes" "(Ljava/nio/charset/Charset;)[B") + (store bytes) + (load-function write_u2) + (load w) + (load-function byte_array_length) + (load bytes) + (invoke 1) + (invoke 2) + (pop) + (load-function write_bytes) + (load w) + (load bytes) + (invoke 2) + (return) + (label try_class_string) + (load tag) + (lconst 7) + (invokevirtual "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") + (ifne write_one_index) + (load tag) + (lconst 8) + (invokevirtual "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") + (ifeq try_long) + (label write_one_index) + (load-function write_u2) + (load w) + (load-function cp_value) + (load entry) + (invoke 1) + (invoke 2) + (return) + (label try_long) + (load tag) + (lconst 5) + (invokevirtual "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") + (ifeq write_pair) + (load-function write_long) + (load w) + (load-function cp_value) + (load entry) + (invoke 1) + (invoke 2) + (return) + (label write_pair) + (load-function cp_value) + (load entry) + (invoke 1) + (store p) + (load-function write_u2) + (load w) + (load-function pair_a) + (load p) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function pair_b) + (load p) + (invoke 1) + (invoke 2) + (return)) + +(function class_bytes (cf) + (load-function cp_utf8) + (load cf) + (sconst "Code") + (invoke 2) + (pop) + (load-function writer) + (invoke 0) + (store w) + (load-function write_u4) + (load w) + (lconst 3405691582) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 49) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (lconst 1) + (ladd) + (invoke 2) + (pop) + (lconst 0) + (store i) + (label cp_loop) + (load i) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (llt) + (jump-if-false cp_done) + (load-function class_cp) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (store entry) + (load entry) + (jump-if-false cp_next) + (load-function write_cp) + (load w) + (load entry) + (invoke 2) + (pop) + (label cp_next) + (load i) + (lconst 1) + (ladd) + (store i) + (jump cp_loop) + (label cp_done) + (load-function write_u2) + (load w) + (lconst 49) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function cp_class) + (load cf) + (load-function class_name) + (load cf) + (invoke 1) + (invoke 2) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function cp_class) + (load cf) + (sconst "java/lang/Object") + (invoke 2) + (invoke 2) + (pop) + (load-function write_list_u2) + (load w) + (load-function class_interfaces) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (invoke 2) + (pop) + (load-function write_fields) + (load w) + (load cf) + (invoke 2) + (pop) + (load-function write_methods) + (load w) + (load cf) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) + (pop) + (load-function writer_bytes) + (load w) + (invoke 1) + (return)) + +(function write_list_u2 (w xs) + (load-function write_u2) + (load w) + (load xs) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (invoke 2) + (pop) + (lconst 0) + (store i) + (label loop) + (load i) + (load xs) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (llt) + (jump-if-false done) + (load-function write_u2) + (load w) + (load xs) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (invoke 2) + (pop) + (load i) + (lconst 1) + (ladd) + (store i) + (jump loop) + (label done) + (aconst-null) + (return)) + +(function write_fields (w cf) + (load-function class_fields) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (store fields) + (load-function write_u2) + (load w) + (load fields) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (invoke 2) + (pop) + (lconst 0) + (store i) + (label loop) + (load i) + (load fields) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (llt) + (jump-if-false done) + (load fields) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (store f) + (load-function write_u2) + (load w) + (load-function field_access) + (load f) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function field_name) + (load f) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function field_desc) + (load f) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) + (pop) + (load i) + (lconst 1) + (ladd) + (store i) + (jump loop) + (label done) + (aconst-null) + (return)) + +(function write_methods (w cf) + (load-function class_methods) + (load cf) + (invoke 1) + (checkcast "java/util/ArrayList") + (store methods) + (load-function write_u2) + (load w) + (load methods) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (invoke 2) + (pop) + (lconst 0) + (store i) + (label loop) + (load i) + (load methods) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (llt) + (jump-if-false done) + (load-function method_write) + (load methods) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (load w) + (invoke 2) + (pop) + (load i) + (lconst 1) + (ladd) + (store i) + (jump loop) + (label done) + (aconst-null) + (return)) + +(function method_code (cf access name desc) + (new "java/util/ArrayList") + (dup) + (invokespecial "java/util/ArrayList" "<init>" "()V") + (store m) + (load-function rec_add) + (load m) + (load cf) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load access) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function cp_utf8) + (load cf) + (load name) + (invoke 2) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function cp_utf8) + (load cf) + (load desc) + (invoke 2) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 65535) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokestatic "java/nio/ByteBuffer" "allocate" "(I)Ljava/nio/ByteBuffer;") + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (load-function new_list) + (invoke 0) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 64) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 2) + (invoke 2) + (pop) + (load-function rec_add) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load m) + (return)) + +(function method_cf (m) + (load-function rec_get) + (load m) + (lconst 0) + (invoke 2) + (return)) + +(function method_access (m) + (load-function rec_get) + (load m) + (lconst 1) + (invoke 2) + (return)) + +(function method_name_index (m) + (load-function rec_get) + (load m) + (lconst 2) + (invoke 2) + (return)) + +(function method_desc_index (m) + (load-function rec_get) + (load m) + (lconst 3) + (invoke 2) + (return)) + +(function method_code_buffer (m) + (load-function rec_get) + (load m) + (lconst 4) + (invoke 2) + (checkcast "java/nio/ByteBuffer") + (return)) + +(function method_labels (m) + (load-function rec_get) + (load m) + (lconst 5) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function method_patches (m) + (load-function rec_get) + (load m) + (lconst 6) + (invoke 2) + (checkcast "java/util/ArrayList") + (return)) + +(function method_max_stack (m) + (load-function rec_get) + (load m) + (lconst 7) + (invoke 2) + (return)) + +(function method_max_locals (m) + (load-function rec_get) + (load m) + (lconst 8) + (invoke 2) + (return)) + +(function method_set_max_locals (m value) + (load-function rec_set) + (load m) + (lconst 8) + (load value) + (invoke 3) + (return)) + +(function method_next_internal (m) + (load-function rec_get) + (load m) + (lconst 9) + (invoke 2) + (store v) + (load-function rec_set) + (load m) + (lconst 9) + (load v) + (lconst 1) + (ladd) + (invoke 3) + (pop) + (load v) + (return)) + +(function code_pos (m) + (load-function method_code_buffer) + (load m) + (invoke 1) + (checkcast "java/nio/ByteBuffer") + (invokevirtual "java/nio/ByteBuffer" "position" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (return)) + +(function code_put_byte (m value) + (load-function method_code_buffer) + (load m) + (invoke 1) + (checkcast "java/nio/ByteBuffer") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/nio/ByteBuffer" "put" "(B)Ljava/nio/ByteBuffer;") + (pop) + (aconst-null) + (return)) + +(function code_put_short (m value) + (load-function method_code_buffer) + (load m) + (invoke 1) + (checkcast "java/nio/ByteBuffer") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/nio/ByteBuffer" "putShort" "(S)Ljava/nio/ByteBuffer;") + (pop) + (aconst-null) + (return)) + +(function code_patch_short (m pos value) + (load-function method_code_buffer) + (load m) + (invoke 1) + (checkcast "java/nio/ByteBuffer") + (load pos) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (load value) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/nio/ByteBuffer" "putShort" "(IS)Ljava/nio/ByteBuffer;") + (pop) + (aconst-null) + (return)) + +(function method_code_bytes (m) + (load-function method_code_buffer) + (load m) + (invoke 1) + (checkcast "java/nio/ByteBuffer") + (invokevirtual "java/nio/ByteBuffer" "array" "()[B") + (load-function code_pos) + (load m) + (invoke 1) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokestatic "java/util/Arrays" "copyOf" "([BI)[B") + (return)) + +(function method_lookup_label (m label) + (load-function method_labels) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (lconst 1) + (lsub) + (store i) + (label loop) + (load i) + (lconst 0) + (llt) + (jump-if-false check) + (aconst-null) + (return) + (label check) + (load-function method_labels) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (store p) + (load label) + (load-function pair_a) + (load p) + (invoke 1) + (invokevirtual "java/lang/Object" "equals" "(Ljava/lang/Object;)Z") + (ifeq next) + (load-function pair_b) + (load p) + (invoke 1) + (return) + (label next) + (load i) + (lconst 1) + (lsub) + (store i) + (jump loop) + (aconst-null) + (return)) + +(function method_label (m label) + (load-function method_lookup_label) + (load m) + (load label) + (invoke 2) + (jump-if-false ok) + (new "java/lang/RuntimeException") + (dup) + (invokespecial "java/lang/RuntimeException" "<init>" "()V") + (athrow) + (label ok) + (load-function method_labels) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function pair) + (load label) + (load-function code_pos) + (load m) + (invoke 1) + (invoke 2) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function method_branch (m opcode label) + (load-function code_pos) + (load m) + (invoke 1) + (store op_pos) + (load-function code_put_byte) + (load m) + (load opcode) + (invoke 2) + (pop) + (load-function code_pos) + (load m) + (invoke 1) + (store patch_pos) + (load-function code_put_short) + (load m) + (lconst 0) + (invoke 2) + (pop) + (load-function method_patches) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (load-function branch_patch) + (load label) + (load op_pos) + (load patch_pos) + (invoke 3) + (invokevirtual "java/util/ArrayList" "add" "(Ljava/lang/Object;)Z") + (pop) + (aconst-null) + (return)) + +(function finish_labels (m) + (lconst 0) + (store i) + (label loop) + (load i) + (load-function method_patches) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (invokevirtual "java/util/ArrayList" "size" "()I") + (i2l) + (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (llt) + (jump-if-false done) + (load-function method_patches) + (load m) + (invoke 1) + (checkcast "java/util/ArrayList") + (load i) + (checkcast "java/lang/Long") + (invokevirtual "java/lang/Long" "intValue" "()I") + (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") + (store p) + (load-function method_lookup_label) + (load m) + (load-function patch_label) + (load p) + (invoke 1) + (invoke 2) + (store target) + (load target) + (jump-if-false bad) + (load-function code_patch_short) + (load m) + (load-function patch_patch_pos) + (load p) + (invoke 1) + (load target) + (checkcast "java/lang/Long") + (load-function patch_op_pos) + (load p) + (invoke 1) + (checkcast "java/lang/Long") + (lsub) + (invoke 3) + (pop) + (load i) + (lconst 1) + (ladd) + (store i) + (jump loop) + (label bad) + (new "java/lang/RuntimeException") + (dup) + (invokespecial "java/lang/RuntimeException" "<init>" "()V") + (athrow) + (label done) + (aconst-null) + (return)) + +(function method_write (m w) + (load-function finish_labels) + (load m) + (invoke 1) + (pop) + (load-function method_code_bytes) + (load m) + (invoke 1) + (store bytes) + (load-function write_u2) + (load w) + (load-function method_access) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_name_index) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_desc_index) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function cp_utf8) + (load-function method_cf) + (load m) + (invoke 1) + (sconst "Code") + (invoke 2) + (invoke 2) + (pop) + (load-function write_u4) + (load w) + (load-function byte_array_length) + (load bytes) + (invoke 1) + (lconst 12) + (ladd) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_max_stack) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (load-function method_max_locals) + (load m) + (invoke 1) + (invoke 2) + (pop) + (load-function write_u4) + (load w) + (load-function byte_array_length) + (load bytes) + (invoke 1) + (invoke 2) + (pop) + (load-function write_bytes) + (load w) + (load bytes) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) + (pop) + (load-function write_u2) + (load w) + (lconst 0) + (invoke 2) + (return)) diff --git a/stage1/compiler.lql b/stage1/compiler.lql index 0074fd9..eb6274a 100644 --- a/stage1/compiler.lql +++ b/stage1/compiler.lql @@ -15,9 +15,10 @@ (new "java/lang/StringBuilder") (dup) (invokespecial "java/lang/StringBuilder" "<init>" "()V") + (load-function class_name) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (getfield "com/tailrecursion/larquil/stage0/ClassFile" "name" "Ljava/lang/String;") + (invoke 1) + (checkcast "java/lang/String") (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") (sconst ".class") (invokevirtual "java/lang/StringBuilder" "append" "(Ljava/lang/String;)Ljava/lang/StringBuilder;") @@ -42,9 +43,10 @@ (load file) (checkcast "java/io/File") (invokevirtual "java/io/File" "toPath" "()Ljava/nio/file/Path;") + (load-function class_bytes) (load cf) - (checkcast "com/tailrecursion/larquil/stage0/ClassFile") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "bytes" "()[B") + (invoke 1) + (checkcast "[B") (iconst 0) (anewarray "java/nio/file/OpenOption") (invokestatic "java/nio/file/Files" "write" "(Ljava/nio/file/Path;[B[Ljava/nio/file/OpenOption;)Ljava/nio/file/Path;") diff --git a/stage1/emit.lql b/stage1/emit.lql index c35770d..f464735 100644 --- a/stage1/emit.lql +++ b/stage1/emit.lql @@ -1,256 +1,327 @@ -; First Stage 1 compiler chunk: bytecode emission helpers. -; These functions operate on the Stage 0 MethodCode object for now. +; Stage 1 bytecode emission helpers backed by Larquil-owned classfile data. (function emit_u1 (m opcode) + (load-function code_put_byte) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load opcode) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "u1" "(I)V") + (invoke 2) (lconst 0) (return)) (function emit_u2 (m value) + (load-function code_put_short) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load value) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "u2" "(I)V") + (invoke 2) (lconst 0) (return)) (function emit_push_int (m value) + (load-function emit_u1) + (load m) + (lconst 17) + (invoke 2) + (pop) + (load-function emit_u2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load value) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "pushInt" "(I)V") + (invoke 2) (lconst 0) (return)) (function emit_aload (m slot) + (load-function emit_u1) + (load m) + (lconst 196) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 25) + (invoke 2) + (pop) + (load-function emit_u2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load slot) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "aload" "(I)V") + (invoke 2) (lconst 0) (return)) (function emit_astore (m slot) + (load-function emit_u1) + (load m) + (lconst 196) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 58) + (invoke 2) + (pop) + (load-function emit_u2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load slot) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "astore" "(I)V") + (invoke 2) (lconst 0) (return)) (function emit_lconst (m value) + (load-function emit_u1) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (lconst 20) + (invoke 2) + (pop) + (load-function emit_u2) + (load m) + (load-function cp_long) + (load-function method_cf) + (load m) + (invoke 1) (load value) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "longValue" "()J") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "lconst" "(J)V") + (invoke 2) + (invoke 2) + (pop) + (load-function emit_invokestatic) + (load m) + (sconst "java/lang/Long") + (sconst "valueOf") + (sconst "(J)Ljava/lang/Long;") + (invoke 4) (lconst 0) (return)) (function emit_sconst (m value) + (load-function emit_u1) + (load m) + (lconst 19) + (invoke 2) + (pop) + (load-function emit_u2) + (load m) + (load-function cp_string) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load value) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "sconst" "(Ljava/lang/String;)V") + (invoke 2) + (invoke 2) + (lconst 0) + (return)) + +(function emit_ref2 (m opcode idx) + (load-function emit_u1) + (load m) + (load opcode) + (invoke 2) + (pop) + (load-function emit_u2) + (load m) + (load idx) + (invoke 2) (lconst 0) (return)) (function emit_getstatic (m owner name descriptor) + (load-function emit_ref2) + (load m) + (lconst 178) + (load-function cp_fieldref) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "getstatic" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_putstatic (m owner name descriptor) + (load-function emit_ref2) + (load m) + (lconst 179) + (load-function cp_fieldref) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "putstatic" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_getfield (m owner name descriptor) + (load-function emit_ref2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (lconst 180) + (load-function cp_fieldref) + (load-function method_cf) + (load m) + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "getfield" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_putfield (m owner name descriptor) + (load-function emit_ref2) + (load m) + (lconst 181) + (load-function cp_fieldref) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "putfield" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_checkcast (m class) + (load-function emit_ref2) + (load m) + (lconst 192) + (load-function cp_class) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load class) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "checkcast" "(Ljava/lang/String;)V") - (lconst 0) + (invoke 2) + (invoke 3) (return)) (function emit_anewarray (m class) + (load-function emit_ref2) + (load m) + (lconst 189) + (load-function cp_class) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load class) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "anewarray" "(Ljava/lang/String;)V") - (lconst 0) + (invoke 2) + (invoke 3) (return)) (function emit_instanceof (m class) + (load-function emit_ref2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (lconst 193) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "u1" "(I)V") + (load-function cp_class) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (getfield "com/tailrecursion/larquil/stage0/MethodCode" "cf" "Lcom/tailrecursion/larquil/stage0/ClassFile;") + (invoke 1) (load class) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/ClassFile" "cpClass" "(Ljava/lang/String;)I") - (i2l) - (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") - (store idx) - (load-function emit_u2) - (load m) - (load idx) (invoke 2) + (invoke 3) (return)) (function emit_new (m class) + (load-function emit_ref2) + (load m) + (lconst 187) + (load-function cp_class) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load class) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "newobj" "(Ljava/lang/String;)V") - (lconst 0) + (invoke 2) + (invoke 3) (return)) (function emit_invokespecial (m owner name descriptor) + (load-function emit_ref2) + (load m) + (lconst 183) + (load-function cp_methodref) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "invokespecial" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_invokevirtual (m owner name descriptor) + (load-function emit_ref2) + (load m) + (lconst 182) + (load-function cp_methodref) + (load-function method_cf) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "invokevirtual" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_invokestatic (m owner name descriptor) + (load-function emit_ref2) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (lconst 184) + (load-function cp_methodref) + (load-function method_cf) + (load m) + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "invokestatic" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") - (lconst 0) + (invoke 4) + (invoke 3) (return)) (function emit_invokeinterface (m owner name descriptor count) + (load-function emit_u1) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") + (lconst 185) + (invoke 2) + (pop) + (load-function emit_u2) + (load m) + (load-function cp_interface_methodref) + (load-function method_cf) + (load m) + (invoke 1) (load owner) - (checkcast "java/lang/String") (load name) - (checkcast "java/lang/String") (load descriptor) - (checkcast "java/lang/String") + (invoke 4) + (invoke 2) + (pop) + (load-function emit_u1) + (load m) (load count) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "invokeinterface" "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V") + (invoke 2) + (pop) + (load-function emit_u1) + (load m) + (lconst 0) + (invoke 2) (lconst 0) (return)) (function emit_branch (m opcode label) + (load-function method_branch) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load opcode) - (checkcast "java/lang/Long") - (invokevirtual "java/lang/Long" "intValue" "()I") (load label) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "branch" "(ILjava/lang/String;)V") + (invoke 3) (lconst 0) (return)) (function emit_label (m label) + (load-function method_label) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load label) - (checkcast "java/lang/String") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "label" "(Ljava/lang/String;)V") - (lconst 0) - (return)) - -(function finish_labels (m) - (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "finishLabels" "()V") + (invoke 2) (lconst 0) (return)) diff --git a/stage1/instructions.lql b/stage1/instructions.lql index ec5bcec..a71cb4f 100644 --- a/stage1/instructions.lql +++ b/stage1/instructions.lql @@ -256,17 +256,13 @@ (load state) (invoke 1) (store left) + (load-function method_next_internal) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "nextInternal" "()I") - (i2l) - (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (invoke 1) (store n1) + (load-function method_next_internal) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "nextInternal" "()I") - (i2l) - (invokestatic "java/lang/Long" "valueOf" "(J)Ljava/lang/Long;") + (invoke 1) (store n2) (new "java/lang/StringBuilder") (dup) @@ -417,15 +413,16 @@ (lconst 2) (invoke 2) (pop) + (load-function emit_label) (load m) - (checkcast "com/tailrecursion/larquil/stage0/MethodCode") (load xs) (checkcast "java/util/ArrayList") (iconst 1) (invokevirtual "java/util/ArrayList" "get" "(I)Ljava/lang/Object;") (checkcast "com/tailrecursion/larquil/stage0/Symbol") (getfield "com/tailrecursion/larquil/stage0/Symbol" "name" "Ljava/lang/String;") - (invokevirtual "com/tailrecursion/larquil/stage0/MethodCode" "label" "(Ljava/lang/String;)V") + (invoke 2) + (pop) (lconst 0) (return) (label try_aconst_null) diff --git a/test/run.sh b/test/run.sh index f36a9cb..cc45b29 100755 --- a/test/run.sh +++ b/test/run.sh @@ -97,10 +97,6 @@ compile_ok jvm_ops "$ROOT/test/cases/ok/jvm_ops.lql" run_loader jvm_ops com.tailrecursion.larquil.stage0.jvm_ops expect_output 7 -compile_ok stage1_emit "$ROOT/stage1/emit.lql" -test -f "$OUT/stage1_emit/com/tailrecursion/larquil/stage0/emit__emit_u1.class" || fail "stage1 emit helper class exists" -ok "stage1 emit class files" - compile_ok stage1_core "$ROOT/stage1/core.lql" test -f "$OUT/stage1_core/com/tailrecursion/larquil/stage0/core__lookup.class" || fail "stage1 core helper class exists" ok "stage1 core class files" @@ -111,7 +107,7 @@ ok "stage1 munge class files" aggregate="$OUT/stage1_compiler_src/compiler.lql" mkdir -p "$OUT/stage1_compiler_src" -cat "$ROOT/stage1/core.lql" "$ROOT/stage1/munge.lql" "$ROOT/stage1/forms.lql" "$ROOT/stage1/reader.lql" "$ROOT/stage1/emit.lql" "$ROOT/stage1/instructions.lql" "$ROOT/stage1/backend.lql" "$ROOT/stage1/compiler.lql" > "$aggregate" +cat "$ROOT/stage1/core.lql" "$ROOT/stage1/munge.lql" "$ROOT/stage1/forms.lql" "$ROOT/stage1/reader.lql" "$ROOT/stage1/classfile.lql" "$ROOT/stage1/emit.lql" "$ROOT/stage1/instructions.lql" "$ROOT/stage1/backend.lql" "$ROOT/stage1/compiler.lql" > "$aggregate" compile_ok stage1_compiler "$aggregate" test -f "$OUT/stage1_compiler/com/tailrecursion/larquil/stage0/compiler__is_named_function.class" || fail "stage1 aggregate helper class exists" ok "stage1 aggregate class files"