Skip to content

Commit

Permalink
Grow lua stack instead of creating it at maximum size
Browse files Browse the repository at this point in the history
 Also double the default size
  • Loading branch information
SquidDev committed Mar 15, 2016
1 parent 300ef76 commit 00799fb
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 47 deletions.
4 changes: 2 additions & 2 deletions src/main/java/org/squiddev/cobalt/ErrorFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
package org.squiddev.cobalt;

import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugInfo;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.lib.DebugLib;

/**
Expand Down Expand Up @@ -104,7 +104,7 @@ public static LuaError operandError(LuaState state, LuaValue operand, String ver
String type = operand.typeName();
LuaString[] kind = null;
if (stack >= 0) {
DebugInfo info = DebugHandler.getDebugState(state.getCurrentThread()).getDebugInfo();
DebugFrame info = DebugHandler.getDebugState(state.getCurrentThread()).getStack();
if (info != null && info.closure != null) {
if (stack < info.closure.getPrototype().maxstacksize) {
kind = DebugLib.getobjname(info, stack);
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/squiddev/cobalt/LuaThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
package org.squiddev.cobalt;

import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugInfo;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugState;
import org.squiddev.cobalt.function.LuaFunction;
import org.squiddev.cobalt.lib.CoroutineLib;
Expand Down Expand Up @@ -92,8 +92,6 @@ public class LuaThread extends LuaValue {
*/
public LuaValue err;

public static final int MAX_CALLSTACK = 256;

public final LuaState luaState;

/**
Expand Down Expand Up @@ -186,7 +184,7 @@ public boolean isAlive() {
* @return LuaFunction on the call stack, or null if outside of range of active stack
*/
public static LuaFunction getCallstackFunction(LuaState state, int level) {
DebugInfo info = DebugHandler.getDebugState(state.currentThread).getDebugInfo(level);
DebugFrame info = DebugHandler.getDebugState(state.currentThread).getDebugInfo(level);
return info == null ? null : info.func;
}

Expand Down Expand Up @@ -271,8 +269,10 @@ public synchronized void run() {
result = function.invoke(state, a);
} catch (LuaError e) {
error = e.value;
} catch (StackOverflowError e) {
error = valueOf("stack overflow");
} catch (Throwable t) {
error = valueOf(t.getMessage());
error = valueOf("vm error: " + t.toString());
} finally {
markDead();
notify();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* Each thread will get a DebugState attached to it by the debug library
* which will track function calls, hook functions, etc.
*/
public final class DebugInfo {
public final class DebugFrame {
/**
* The debug info's function
*/
Expand All @@ -52,18 +52,18 @@ public final class DebugInfo {
*/
public LuaValue[] stack;

public final DebugInfo previous;
public final DebugFrame previous;


public Varargs varargs, extras;
public int pc, top;

public DebugInfo(DebugInfo previous) {
public DebugFrame(DebugFrame previous) {
this.previous = previous;
func = null;
}

public DebugInfo(LuaFunction func) {
public DebugFrame(LuaFunction func) {
pc = -1;
previous = null;
setFunction(func);
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/squiddev/cobalt/debug/DebugHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public final DebugState getDebugState() {
* @param func the function called
*/
public void onCall(DebugState ds, LuaFunction func) {
DebugInfo di = ds.pushInfo();
DebugFrame di = ds.pushInfo();
di.setFunction(func);

if (!ds.inhook && ds.hookcall) ds.callHookFunc(CALL, NIL);
Expand All @@ -79,8 +79,8 @@ public void onCall(DebugState ds, LuaFunction func) {
* @param stack The current lua stack
* @return The pushed info
*/
public DebugInfo onCall(DebugState ds, LuaClosure func, Varargs args, LuaValue[] stack) {
DebugInfo di = ds.pushInfo();
public DebugFrame onCall(DebugState ds, LuaClosure func, Varargs args, LuaValue[] stack) {
DebugFrame di = ds.pushInfo();
di.setFunction(func, args, stack);

if (!ds.inhook && ds.hookcall) {
Expand Down Expand Up @@ -117,7 +117,7 @@ public void onReturn(DebugState ds) {
* @param extras Extra arguments
* @param top The top of the callstack
*/
public void onInstruction(DebugState ds, DebugInfo di, int pc, Varargs extras, int top) {
public void onInstruction(DebugState ds, DebugFrame di, int pc, Varargs extras, int top) {
Prototype prototype = ds.inhook || di.closure == null ? null : di.closure.getPrototype();
int oldPc = di.pc;

Expand Down
51 changes: 32 additions & 19 deletions src/main/java/org/squiddev/cobalt/debug/DebugState.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
* DebugState is associated with a Thread
*/
public final class DebugState {
public static final int MAX_SIZE = 512;

public static final int DEFAULT_SIZE = 8;

private static final DebugFrame[] EMPTY = new DebugFrame[0];

/**
* The thread that owns this object
*/
Expand All @@ -55,7 +61,7 @@ public final class DebugState {
/**
* The stack of debug info
*/
private final DebugInfo[] debugInfo = new DebugInfo[LuaThread.MAX_CALLSTACK];
private DebugFrame[] stack = EMPTY;

/**
* The hook function to call
Expand Down Expand Up @@ -83,12 +89,6 @@ public DebugState(LuaThread thread) {
this.handler = state.debug;
}

public DebugInfo getInfo(int call) {
DebugInfo di = debugInfo[call];
if (di == null) debugInfo[call] = di = new DebugInfo(call == 0 ? null : getInfo(call - 1));
return di;
}

public void onCall(LuaFunction func) {
handler.onCall(this, func);
}
Expand All @@ -102,19 +102,32 @@ public void onReturn() {
*
* @return The created info
*/
protected DebugInfo pushInfo() {
protected DebugFrame pushInfo() {
int top = this.top + 1;
if (top >= LuaThread.MAX_CALLSTACK) throw new LuaError("stack overflow");

DebugFrame[] frames = stack;
int length = frames.length;
if (top >= length) {
if (top >= MAX_SIZE) throw new LuaError("stack overflow");

int newSize = length == 0 ? DEFAULT_SIZE : length + (length / 2);
DebugFrame[] f = new DebugFrame[newSize];
System.arraycopy(frames, 0, f, 0, frames.length);
for (int i = frames.length; i < newSize; ++i) {
f[i] = new DebugFrame(i > 0 ? f[i - 1] : null);
}
frames = stack = f;
}

this.top = top;
return getInfo(top);
return frames[top];
}

/**
* Pop a debug info off the stack
*/
protected void popInfo() {
debugInfo[top--].clear();
stack[top--].clear();
}

protected void callHookFunc(LuaString type, LuaValue arg) {
Expand Down Expand Up @@ -154,8 +167,8 @@ public void setHook(LuaFunction func, boolean call, boolean line, boolean rtrn,
*
* @return The top debug info or {@code null}
*/
public DebugInfo getDebugInfo() {
return top >= 0 ? debugInfo[top] : null;
public DebugFrame getStack() {
return top >= 0 ? stack[top] : null;
}

/**
Expand All @@ -164,8 +177,8 @@ public DebugInfo getDebugInfo() {
* @param level The level to get at
* @return The debug info or {@code null}
*/
public DebugInfo getDebugInfo(int level) {
return level >= 0 && level <= top ? debugInfo[top - level] : null;
public DebugFrame getDebugInfo(int level) {
return level >= 0 && level <= top ? stack[top - level] : null;
}

/**
Expand All @@ -174,13 +187,13 @@ public DebugInfo getDebugInfo(int level) {
* @param func The function to find
* @return The debug info for this function
*/
public DebugInfo findDebugInfo(LuaFunction func) {
public DebugFrame findDebugInfo(LuaFunction func) {
for (int i = top - 1; --i >= 0; ) {
if (debugInfo[i].func == func) {
return debugInfo[i];
if (stack[i].func == func) {
return stack[i];
}
}
return new DebugInfo(func);
return new DebugFrame(func);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.squiddev.cobalt.compiler.LoadState;
import org.squiddev.cobalt.compiler.LuaC;
import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugInfo;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugState;

import static org.squiddev.cobalt.Constants.FALSE;
Expand Down Expand Up @@ -219,7 +219,7 @@ protected Varargs execute(LuaState state, LuaValue[] stack, Varargs varargs) {
// debug wants args to this function
DebugHandler handler = state.debug;
DebugState ds = handler.getDebugState();
DebugInfo di = handler.onCall(ds, this, varargs, stack);
DebugFrame di = handler.onCall(ds, this, varargs, stack);

// process instructions
try {
Expand Down
18 changes: 9 additions & 9 deletions src/main/java/org/squiddev/cobalt/lib/DebugLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import org.squiddev.cobalt.*;
import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugInfo;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugState;
import org.squiddev.cobalt.function.LibFunction;
import org.squiddev.cobalt.function.LuaClosure;
Expand Down Expand Up @@ -229,10 +229,10 @@ protected static Varargs _getinfo(LuaState state, Varargs args, LuaValue level0f

// find the stack info
DebugState ds = DebugHandler.getDebugState(thread);
DebugInfo di;
DebugFrame di;
if (func.isNumber()) {
int level = func.checkInteger();
di = level > 0 ? ds.getDebugInfo(level - 1) : new DebugInfo(level0func.checkFunction());
di = level > 0 ? ds.getDebugInfo(level - 1) : new DebugFrame(level0func.checkFunction());
} else {
di = ds.findDebugInfo(func.checkFunction());
}
Expand Down Expand Up @@ -309,7 +309,7 @@ private static Varargs _getlocal(LuaState state, Varargs args) {
int local = args.arg(i).checkInteger();

DebugState ds = DebugHandler.getDebugState(thread);
DebugInfo di = ds.getDebugInfo(level - 1);
DebugFrame di = ds.getDebugInfo(level - 1);
LuaString name = (di != null ? di.getLocalName(local) : null);
if (name != null) {
LuaValue value = di.stack[local - 1];
Expand All @@ -329,7 +329,7 @@ private static Varargs _setlocal(LuaState state, Varargs args) {
LuaValue value = args.arg(a++);

DebugState ds = DebugHandler.getDebugState(thread);
DebugInfo di = ds.getDebugInfo(level - 1);
DebugFrame di = ds.getDebugInfo(level - 1);
LuaString name = (di != null ? di.getLocalName(local) : null);
if (name != null) {
di.stack[local - 1] = value;
Expand Down Expand Up @@ -444,7 +444,7 @@ public static String traceback(LuaThread thread, int level) {
StringBuilder sb = new StringBuilder();
DebugState ds = DebugHandler.getDebugState(thread);
sb.append("stack traceback:");
DebugInfo di = ds.getDebugInfo(level);
DebugFrame di = ds.getDebugInfo(level);
if (di != null) {
sb.append("\n\t");
sb.append(di.sourceline());
Expand All @@ -470,7 +470,7 @@ public static String traceback(LuaThread thread, int level) {
*/
public static String fileline(LuaThread thread) {
DebugState ds = DebugHandler.getDebugState(thread);
DebugInfo di;
DebugFrame di;
for (int i = 0, n = ds.top; i < n; i++) {
di = ds.getDebugInfo(i);
if (di != null && di.closure != null) {
Expand All @@ -482,7 +482,7 @@ public static String fileline(LuaThread thread) {

public static String fileline(LuaThread thread, int level) {
DebugState ds = DebugHandler.getDebugState(thread);
DebugInfo di = ds.getDebugInfo(level);
DebugFrame di = ds.getDebugInfo(level);
return di != null ? di.sourceline() : null;
}

Expand All @@ -494,7 +494,7 @@ static void lua_assert(boolean x) {


// return StrValue[] { name, namewhat } if found, null if not
public static LuaString[] getobjname(DebugInfo di, int stackpos) {
public static LuaString[] getobjname(DebugFrame di, int stackpos) {
LuaString name;
if (di.closure != null) { // a Lua function?
Prototype p = di.closure.getPrototype();
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/squiddev/cobalt/ProtectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugInfo;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugState;

import java.io.IOException;
Expand Down Expand Up @@ -51,7 +51,7 @@ public void poll() {
}

@Override
public void onInstruction(DebugState ds, DebugInfo di, int pc, Varargs extras, int top) {
public void onInstruction(DebugState ds, DebugFrame di, int pc, Varargs extras, int top) {
poll();
super.onInstruction(ds, di, pc, extras, top);
}
Expand Down

0 comments on commit 00799fb

Please sign in to comment.