Basic facility to read/write bytecode.

These classes are meant for reading and writing bytecode at the lowest
possible level, in particular without layering any interpretation of
the instructions beyond understanding the instruction formats. (For
example, constant indices remain numbers and aren't tied to objects
representing constants.)

This patch represents a work-in-progress that compiles but is as yet
not hooked up to anything else. Hooking it all up will happen in
one or more follow-on patches.

Change-Id: Ifd3b3ff0925dc9dc3d82e507dc1be83cb560031d
diff --git a/opcode-gen/opcode-gen.awk b/opcode-gen/opcode-gen.awk
index 3232bc6..86e7cae 100644
--- a/opcode-gen/opcode-gen.awk
+++ b/opcode-gen/opcode-gen.awk
@@ -103,7 +103,29 @@
     }
 }
 
-emission == "dops-init" {
+emission == "opcode-info-defs" {
+    emissionHandled = 1;
+
+    for (i = 0; i <= MAX_OPCODE; i++) {
+        if (isUnused(i) || isOptimized(i)) continue;
+
+        itype = indexType[i];
+        if ((itype == "none") || (itype == "unknown")) {
+            itype = "null";
+        } else {
+            itype = toupper(itype);
+            gsub(/-/, "_", itype);
+            itype = "IndexType." itype;
+        }
+
+        printf("    public static final Info %s =\n" \
+               "        new Info(DalvOps.%s,\n" \
+               "            InstructionCodec.FORMAT_%s, %s);\n\n", \
+                constName[i], constName[i], toupper(format[i]), itype);
+    }
+}
+
+emission == "dops-init" || emission == "opcode-info-init" {
     emissionHandled = 1;
 
     for (i = 0; i <= MAX_OPCODE; i++) {