Skip to content
This repository has been archived by the owner on Jul 1, 2018. It is now read-only.

Commit

Permalink
Update LuaJC with fix from SquidDev-CC/Studio#13
Browse files Browse the repository at this point in the history
  • Loading branch information
SquidDev committed Mar 22, 2015
1 parent 3c40a68 commit c118a11
Show file tree
Hide file tree
Showing 22 changed files with 1,112 additions and 146 deletions.
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mc_version=1.7.10
forge_version=10.13.2.1291
cc_version=1.73
mod_version=0.1.4
mod_version=0.1.4.1
2 changes: 1 addition & 1 deletion src/main/java/org/luaj/vm2/lib/DebugLib_Rewrite.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
package org.luaj.vm2.lib;

import org.luaj.vm2.*;
import org.luaj.vm2.luajc.IGetSource;
import squiddev.cctweaks.core.luajc.IGetSource;

/**
* Subclass of {@link org.luaj.vm2.lib.LibFunction} which implements the lua standard {@code debug}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/luaj/vm2/lib/StringLib_Rewrite.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import org.luaj.vm2.*;
import org.luaj.vm2.compiler.DumpState;
import org.luaj.vm2.luajc.IGetSource;
import squiddev.cctweaks.core.luajc.IGetSource;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/squiddev/cctweaks/core/asm/AsmUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.objectweb.asm.Type;
import org.objectweb.asm.util.CheckClassAdapter;
import org.objectweb.asm.util.TraceClassVisitor;
import squiddev.cctweaks.core.utils.DebugLogger;

import java.io.PrintWriter;
import java.io.StringWriter;
Expand Down Expand Up @@ -85,8 +86,8 @@ public static void validateClass(ClassReader reader, ClassLoader loader) {
String contents = writer.toString();
if (contents.length() > 0) {
reader.accept(new TraceClassVisitor(printWriter), 0);
System.out.println("Dump for " + reader.getClassName());
System.out.println(writer);
DebugLogger.error("Dump for " + reader.getClassName());
DebugLogger.error(contents);
throw new RuntimeException("Generation error");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static byte[] patchLuaMachine(byte[] bytes) {
InsnListSection found = ASMMatcher.findOnce(method.instructions, new InsnListSection(jsePlatform), true);

InsnList insert = new InsnList();
insert.add(new MethodInsnNode(INVOKESTATIC, "org/luaj/vm2/luajc/LuaJCRewrite", "install", "()V", false));
insert.add(new MethodInsnNode(INVOKESTATIC, "squiddev/cctweaks/core/luajc/LuaJC", "install", "()V", false));
found.insert(insert);

changed = true;
Expand Down
190 changes: 190 additions & 0 deletions src/main/java/squiddev/cctweaks/core/luajc/BasicBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package squiddev.cctweaks.core.luajc;

import org.luaj.vm2.Lua;
import org.luaj.vm2.Prototype;

import java.util.Vector;

public class BasicBlock {
int pc0, pc1; // range of program counter values for the block
BasicBlock[] prev; // previous basic blocks (0-n of these)
BasicBlock[] next; // next basic blocks (0, 1, or 2 of these)
boolean islive; // true if this block is used

public BasicBlock(Prototype p, int pc0) {
this.pc0 = this.pc1 = pc0;
}

public String toString() {
return (pc0 + 1) + "-" + (pc1 + 1)
+ (prev != null ? " prv: " + str(prev, 1) : "")
+ (next != null ? " nxt: " + str(next, 0) : "")
+ "\n";
}

private String str(BasicBlock[] b, int p) {
if (b == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0, n = b.length; i < n; i++) {
if (i > 0) sb.append(",");
sb.append(String.valueOf(p == 1 ? b[i].pc1 + 1 : b[i].pc0 + 1));
}
sb.append(")");
return sb.toString();
}

public static BasicBlock[] findBasicBlocks(Prototype p) {

// mark beginnings, endings
final int n = p.code.length;
final boolean[] isbeg = new boolean[n];
final boolean[] isend = new boolean[n];
isbeg[0] = true;
BranchVisitor bv = new BranchVisitor(isbeg) {
public void visitBranch(int pc0, int pc1) {
isend[pc0] = true;
isbeg[pc1] = true;
}

public void visitReturn(int pc) {
isend[pc] = true;
}
};
visitBranches(p, bv); // 1st time to mark branches
visitBranches(p, bv); // 2nd time to catch merges

// create basic blocks
final BasicBlock[] blocks = new BasicBlock[n];
for (int i = 0; i < n; i++) {
isbeg[i] = true;
BasicBlock b = new BasicBlock(p, i);
blocks[i] = b;
while (!isend[i] && i + 1 < n && !isbeg[i + 1]) {
blocks[b.pc1 = ++i] = b;
}
}

// count previous, next
final int[] nnext = new int[n];
final int[] nprev = new int[n];
visitBranches(p, new BranchVisitor(isbeg) {
public void visitBranch(int pc0, int pc1) {
nnext[pc0]++;
nprev[pc1]++;
}
});

// allocate and cross-reference
visitBranches(p, new BranchVisitor(isbeg) {
public void visitBranch(int pc0, int pc1) {
if (blocks[pc0].next == null) blocks[pc0].next = new BasicBlock[nnext[pc0]];
if (blocks[pc1].prev == null) blocks[pc1].prev = new BasicBlock[nprev[pc1]];
blocks[pc0].next[--nnext[pc0]] = blocks[pc1];
blocks[pc1].prev[--nprev[pc1]] = blocks[pc0];
}
});
return blocks;
}

abstract public static class BranchVisitor {
final boolean[] isbeg;

public BranchVisitor(boolean[] isbeg) {
this.isbeg = isbeg;
}

public void visitBranch(int frompc, int topc) {
}

public void visitReturn(int atpc) {
}
}

public static void visitBranches(Prototype p, BranchVisitor visitor) {
int sbx, j, c;
int[] code = p.code;
int n = code.length;
for (int i = 0; i < n; i++) {
int ins = code[i];
switch (Lua.GET_OPCODE(ins)) {
case Lua.OP_LOADBOOL:
if (0 == Lua.GETARG_C(ins)) {
break;
}
if (Lua.GET_OPCODE(code[i + 1]) == Lua.OP_JMP) {
throw new IllegalArgumentException("OP_LOADBOOL followed by jump at " + i);
}
visitor.visitBranch(i, i + 2);
continue;
case Lua.OP_EQ:
case Lua.OP_LT:
case Lua.OP_LE:
case Lua.OP_TEST:
case Lua.OP_TESTSET:
case Lua.OP_TFORLOOP:
if (Lua.GET_OPCODE(code[i + 1]) != Lua.OP_JMP) {
throw new IllegalArgumentException("test not followed by jump at " + i);
}
sbx = Lua.GETARG_sBx(code[i + 1]);
++i;
j = i + sbx + 1;
visitor.visitBranch(i, j);
visitor.visitBranch(i, i + 1);
continue;
case Lua.OP_FORLOOP:
sbx = Lua.GETARG_sBx(ins);
j = i + sbx + 1;
visitor.visitBranch(i, j);
visitor.visitBranch(i, i + 1);
continue;
case Lua.OP_JMP:
case Lua.OP_FORPREP:
sbx = Lua.GETARG_sBx(ins);
j = i + sbx + 1;
visitor.visitBranch(i, j);
continue;
case Lua.OP_TAILCALL:
case Lua.OP_RETURN:
visitor.visitReturn(i);
continue;
}
if (i + 1 < n && visitor.isbeg[i + 1]) {
visitor.visitBranch(i, i + 1);
}
}
}

public static BasicBlock[] findLiveBlocks(BasicBlock[] blocks) {
// add reachable blocks
Vector<BasicBlock> next = new Vector<BasicBlock>();
next.addElement(blocks[0]);
while (!next.isEmpty()) {
BasicBlock b = next.elementAt(0);
next.removeElementAt(0);
if (!b.islive) {
b.islive = true;
for (int i = 0, n = b.next != null ? b.next.length : 0; i < n; i++) {
if (!b.next[i].islive) {
next.addElement(b.next[i]);
}
}
}
}

// create list in natural order
Vector<BasicBlock> list = new Vector<BasicBlock>();
for (int i = 0; i < blocks.length; i = blocks[i].pc1 + 1) {
if (blocks[i].islive) {
list.addElement(blocks[i]);
}
}

// convert to array
BasicBlock[] array = new BasicBlock[list.size()];
list.copyInto(array);
return array;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.luaj.vm2.luajc;
package squiddev.cctweaks.core.luajc;

import org.luaj.vm2.Prototype;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.luajc;

package squiddev.cctweaks.core.luajc;

import org.luaj.vm2.*;
import org.luaj.vm2.luajc.function.*;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import squiddev.cctweaks.core.luajc.function.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.objectweb.asm.Opcodes.*;
import static squiddev.cctweaks.core.asm.AsmUtils.TinyMethod;
import static squiddev.cctweaks.core.asm.AsmUtils.constantOpcode;

public class JavaBuilderRewrite {
public class JavaBuilder {
public static final String PROTOTYPE_NAME = "PROTOTYPE";

protected static final String TYPE_LOCALUPVALUE = Type.getDescriptor(LuaValue[].class);
Expand Down Expand Up @@ -228,7 +227,7 @@ protected static String getSignature(Class<?> classObj, String invokeName, Class
*/
protected int pc = 0;

public JavaBuilderRewrite(ProtoInfo pi, String className, String filename) {
public JavaBuilder(ProtoInfo pi, String className, String filename) {
this.pi = pi;
this.p = pi.prototype;

Expand Down Expand Up @@ -291,8 +290,8 @@ public JavaBuilderRewrite(ProtoInfo pi, String className, String filename) {
main.visitLabel(start);

// Create the slots for current line and stack
slots.add(new Slot(sourceSlot = ++maxLocals, "source", TYPE_SOURCE));
slots.add(new Slot(callStackSlot = ++maxLocals, "callStack", TYPE_CALLSTACK));
sourceSlot = ++maxLocals;
callStackSlot = ++maxLocals;

// Create source object
main.visitTypeInsn(NEW, CLASS_SOURCE);
Expand Down Expand Up @@ -400,7 +399,15 @@ public byte[] completeClass() {
// Finish main function
main.visitLabel(end);
main.visitMaxs(0, 0);
for (Slot slot : slots) slot.inject();

// Add upvalue & local value slot names
for (Map.Entry<Integer, Integer> slot : plainSlotVars.entrySet()) {
main.visitLocalVariable(PREFIX_LOCAL_SLOT + "_" + slot.getKey(), TYPE_LUAVALUE, null, start, end, slot.getValue());
}

for (Map.Entry<Integer, Integer> slot : upvalueSlotVars.entrySet()) {
main.visitLocalVariable(PREFIX_UPVALUE_SLOT + "_" + slot.getKey(), TYPE_LOCALUPVALUE, null, start, end, slot.getValue());
}

main.visitEnd();

Expand Down Expand Up @@ -432,43 +439,20 @@ public void loadBoolean(boolean b) {

protected Map<Integer, Integer> plainSlotVars = new HashMap<Integer, Integer>();
protected Map<Integer, Integer> upvalueSlotVars = new HashMap<Integer, Integer>();
protected List<Slot> slots = new ArrayList<Slot>();

protected class Slot {
public final int javaSlot;
public final String name;
public final String type;

public Slot(int javaSlot, String name, String type) {
this.javaSlot = javaSlot;
this.name = name;
this.type = type;
}

public void inject() {
main.visitLocalVariable(name, type, null, start, end, javaSlot);
}
}

protected int findSlot(int luaSlot, Map<Integer, Integer> map, String name, String type) {
protected int findSlot(int luaSlot, Map<Integer, Integer> map) {
if (map.containsKey(luaSlot)) return map.get(luaSlot);

// This will always be an Upvalue/LuaValue so the slot size is 1 as it is a reference
int javaSlot = ++maxLocals;
map.put(luaSlot, javaSlot);
if (name != null) {
slots.add(new Slot(javaSlot, name, type));
}
return javaSlot;
}

protected int findSlotIndex(int slot, boolean isUpvalue) {
LuaString varName = p.getlocalname(slot, pc);
String name = varName == null ? Integer.toString(slot) : ("_" + varName.toString());

return isUpvalue ?
findSlot(slot, upvalueSlotVars, PREFIX_UPVALUE_SLOT + name, TYPE_LOCALUPVALUE) :
findSlot(slot, plainSlotVars, PREFIX_LOCAL_SLOT + name, TYPE_LUAVALUE);
findSlot(slot, upvalueSlotVars) :
findSlot(slot, plainSlotVars);
}

public void loadLocal(int pc, int slot) {
Expand Down
Loading

0 comments on commit c118a11

Please sign in to comment.