Skip to content

Commit 1d29c19

Browse files
committed
0.4.0 - Class file to source work-in-progress. 'Opcodes' enum cleanup. 'Settings' cleanup and moved to 'ConstantPoolExtensions', 'ClassFile', and 'ClassFileAttributes'.
1 parent a9d8931 commit 1d29c19

File tree

71 files changed

+2542
-1415
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2542
-1415
lines changed

Diff for: .classpath

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
33
<classpathentry kind="src" path="src"/>
4-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre-9.0.1">
4+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
55
<attributes>
66
<attribute name="module" value="true"/>
77
</attributes>

Diff for: CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,21 @@ This project does its best to adhere to [Semantic Versioning](http://semver.org/
44

55

66
--------
7-
### [0.3.0](N/A) - 2017-12-22
7+
### [0.4.0](N/A) - 2020-06-29
8+
#### Added
9+
* `ClassFileToSource` and `CodeToSource` work-in-progress to convert class file back into Java source code
10+
* `CONSTANT_CP_Info.toShortString()` added interface method and to implementations
11+
12+
#### Changed
13+
* Clean up `Settings` mega-utility class. Move methods into `ConstantPoolExtensions`, `ClassFile`, and `ClassFileAttributes`
14+
* Cleaned up `Opcodes`
15+
16+
#### Removed
17+
* Unused `ConstantPoolIndexArray` and `ConstantPoolTag` annotations
18+
19+
20+
--------
21+
### [0.3.0](https://github.com/TeamworkGuy2/ClassLoading/commit/a9d89312f7c97837b332ecda61f6ef38de53f70f) - 2017-12-22
822
#### Changed
923
* Upgrade to Java 9
1024
* Java 9 ClassFile format support:

Diff for: bin/class_loading.jar

2.98 KB
Binary file not shown.

Diff for: extract-opcodes.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/** Extract op codes for twg2.jbcm.Opcodes from oracle's JVM spec html page.
2+
* run the following javascript code in the console tools of the page to extract opcodes.
3+
* https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html
4+
* @author TeamworkGuy2
5+
* @since 2020-06-11
6+
*/
7+
8+
function texts(root, idx, selector, num) {
9+
var elems = root.querySelectorAll(selector);
10+
if(num > 0 && num != elems.length) {
11+
throw new Error("expected " + num + " but found " + elems.length + " elements: " + selector + " (at " + idx + ")");
12+
}
13+
var res = Array.prototype.reduce.call(elems, function (ary, elem) {
14+
ary.push(elem.textContent.trim());
15+
return ary;
16+
}, []);
17+
return res;
18+
}
19+
var baseUrl = "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html";
20+
var sections = Array.prototype.slice.call(document.querySelectorAll(".section-execution"))
21+
22+
res = [];
23+
sections.forEach((el, idx) => {
24+
var operation = texts(el, idx, ".section[title='Operation'] p.norm", 1)[0].split("\n").join(" ").replace(/\s+/g, " ").trim();
25+
var formats = texts(el, idx, ".section .literallayout", -1).map(s => s.split("\n").map(t => t.trim()));
26+
var operandStack = texts(el, idx, ".section[title='Operand Stack'] p.norm", -1).join("\n").split(/[\n]/).map(s => s.trim())
27+
.filter(s => s.length > 0 && (s.startsWith("...") || s.startsWith("[") || s.startsWith("Form ") || s.startsWith("Same as ")/*wide*/ || s === "No change"/*goto, goto_w, iinc, nop, ret, breakpoint*/ || s.indexOf(" ") === -1/*athrow*/));
28+
var description = texts(el, idx, ".norm-dynamic", -1).join(" ").replace(/\s+/g, " ").trim();
29+
var forms = texts(el, idx, ".section[title='Forms'] p.norm", -1).filter(s => s.length > 0);
30+
var hashLink = el.querySelector(".titlepage h3.title a").getAttribute("name");
31+
for(var j = 0; j < forms.length; j++) {
32+
var opCode = parseInt(forms[j].split(" = ")[1].split(" (")[0]);
33+
var name = forms[j].split(" = ")[0];
34+
res.push({ name: name, opCode: opCode, operation: operation, formats: formats, forms: forms, operandStack: operandStack, description: description, hashLink: hashLink });
35+
}
36+
});
37+
res.push({ name: "breakpoint", opCode: 202, operation: "reserved for debuggers", formats: [["breakpoint"]], forms: ["breakpoint"], operandStack: ["No change"], description: "Intended to be used by debuggers to implement breakpoints" });
38+
res.push({ name: "impdep1", opCode: 254, operation: "reserved opcode", formats: [["impdep1"]], forms: ["impdep1"], operandStack: [""], description: "These instructions are intended to provide \"back doors\" or traps to implementation-specific functionality implemented in software and hardware, respectively" });
39+
res.push({ name: "impdep2", opCode: 255, operation: "reserved opcode", formats: [["impdep2"]], forms: ["impdep2"], operandStack: [""], description: "These instructions are intended to provide \"back doors\" or traps to implementation-specific functionality implemented in software and hardware, respectively" });
40+
res = res.sort((a,b) => a.opCode - b.opCode).filter(s => !isNaN(s.opCode)/*mnemonic example at top of page*/);
41+
res.push({ name: "undefined", opCode: -1, operation: "", formats: [[]], forms: [], operandStack: [""], description: "" });
42+
43+
res.map((rr, idx, ary) => {
44+
var opStackOffset = rr.operandStack[0].startsWith("Form ") ? 1 : 0;
45+
var stackPopCount = rr.operandStack[opStackOffset].split(", ").length - 1;
46+
var stackPushCount = rr.operandStack.length > opStackOffset + 1 ? rr.operandStack[opStackOffset + 1].split(", ").length - 1 : 0;
47+
var operandCount = rr.description.indexOf("variable-length instruction") > -1 || rr.name === "wide" ? "Const.UNPREDICTABLE" : (rr.operation.startsWith("reserved") ? "Const.RESERVED" : rr.formats[0].length - 1);
48+
var isCondition = rr.name.startsWith("if");
49+
var isJump = rr.operation.startsWith("Branch ") || rr.name === "jsr" || rr.name === "jsr_w";
50+
var isCpIndex = rr.description.indexOf("index into the run-time constant pool of the current class") > -1;
51+
var isStackManipulate = rr.name.startsWith("dup") || rr.name === "swap";
52+
var isVariableStackPop = rr.operandStack[opStackOffset].indexOf("[arg") > -1;
53+
var types;
54+
var opUtils;
55+
return "\t/* " + String(rr.opCode).padStart(2, ' ') + " " + ("0x" + rr.opCode.toString(16).toUpperCase()).padStart(4, ' ') + " */" +
56+
rr.name.toUpperCase().padEnd(16, ' ') +
57+
"(" + rr.opCode + ", " + operandCount + ", " +
58+
((types = [
59+
(isStackManipulate ? "Type.STACK_MANIPULATE" : null),
60+
(isVariableStackPop ? "Type.POP_UNPREDICTABLE" : null),
61+
(stackPopCount > 0 && !isStackManipulate && !isVariableStackPop ? "Type.POP" + stackPopCount : null),
62+
(stackPushCount > 0 && !isStackManipulate ? "Type.PUSH" + stackPushCount : null),
63+
(rr.name.indexOf("load") === 1 ? "Type.VAR_LOAD" : null),
64+
(rr.name.indexOf("store") === 1 ? "Type.VAR_STORE" : null),
65+
(rr.name.indexOf("aload") === 1 ? "Type.ARRAY_LOAD" : null),
66+
(rr.name.indexOf("astore") === 1 ? "Type.ARRAY_STORE" : null),
67+
(rr.name.indexOf("return") > -1 ? "Type.RETURN" : null),
68+
(isCondition ? "Type.CONDITION" : null),
69+
(isJump ? "Type.JUMP" : null),
70+
(isCpIndex ? "Type.CP_INDEX" : null)
71+
].filter(s => s != null)).length > 0 ? "enums(" + types.join(", ") + ")" : "none(Type.class)") +
72+
", " +
73+
((opUtils = [
74+
(isCondition || isJump ? "IoUtility.offsetModifier(1, " + (rr.name.endsWith("_w") ? 4 : 2) + ")" : null),
75+
(isCpIndex ? "IoUtility.cpIndex(1, " + (rr.name.endsWith("_w") ? 4 : 2) + ")" : null),
76+
(rr.name === "tableswitch" ? "IoUtility.TableswitchOffsetModifier" : null),
77+
(rr.name === "lookupswitch" ? "IoUtility.LookupswitchOffsetModifier" : null)
78+
].filter(s => s != null)).length > 0 ? "Op.of(" + opUtils.join(", ") + ")" : "null") +
79+
")" + (idx < ary.length - 1 ? "," : ";") +
80+
" // " + rr.operation + "," + (!isStackManipulate ? " stack: " + JSON.stringify(rr.operandStack, undefined, " ").split("\n").map(s => s.trim()).join(" ") + "," : "") + (rr.hashLink != null ? " link: " + baseUrl + "#" + rr.hashLink : "");
81+
}).join("\n")

Diff for: package-lib.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"version" : "0.3.0",
2+
"version" : "0.4.0",
33
"name" : "class-loading",
4-
"description" : "Java class file parsing and manipulation",
4+
"description" : "Java class file parsing, manipulation, and to human readable representation",
55
"homepage" : "https://github.com/TeamworkGuy2/ClassLoading",
66
"license" : "MIT",
77
"main" : "./bin/class_loading.jar",

0 commit comments

Comments
 (0)