Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic implementation of persistence #46

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ apply plugin: 'maven-publish'
apply plugin: 'maven'

group = 'org.squiddev'
version = '0.5.1-SNAPSHOT'
version = '0.6.0-SNAPSHOT'

targetCompatibility = sourceCompatibility = 1.8
compileTestJava.sourceCompatibility = compileTestJava.targetCompatibility = 1.8
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/squiddev/cobalt/Lua.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class Lua {
/**
* Version is supplied by ant build task
*/
public static final String _VERSION = "Luaj 0.0";
public static final String _VERSION = "Lua 5.1";

/**
* Use return values from previous op
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/org/squiddev/cobalt/LuaDouble.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,6 @@ public double checkDouble() {
return v;
}

@Override
public String checkString() {
return toString();
}

@Override
public LuaString checkLuaString() {
return strvalue();
Expand All @@ -239,9 +234,4 @@ public LuaValue checkValidKey() throws LuaError {
if (Double.isNaN(v)) throw new LuaError("table index is NaN");
return this;
}

@Override
public double checkArith() {
return v;
}
}
10 changes: 0 additions & 10 deletions src/main/java/org/squiddev/cobalt/LuaInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,8 @@ public double checkDouble() {
return v;
}

@Override
public String checkString() {
return String.valueOf(v);
}

@Override
public LuaString checkLuaString() {
return ValueFactory.valueOf(String.valueOf(v));
}

@Override
public double checkArith() {
return v;
}
}
19 changes: 12 additions & 7 deletions src/main/java/org/squiddev/cobalt/LuaNumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,42 @@ public LuaNumber() {
}

@Override
public LuaNumber checkNumber() {
public final LuaNumber checkNumber() {
return this;
}

@Override
public LuaNumber checkNumber(String errmsg) {
public final LuaNumber checkNumber(String errmsg) {
return this;
}

@Override
public LuaNumber optNumber(LuaNumber defval) {
public final LuaNumber optNumber(LuaNumber defval) {
return this;
}

@Override
public LuaValue toNumber() {
public final LuaValue toNumber() {
return this;
}

@Override
public boolean isNumber() {
public final boolean isNumber() {
return true;
}

@Override
public LuaTable getMetatable(LuaState state) {
public final LuaTable getMetatable(LuaState state) {
return state.numberMetatable;
}

@Override
public double checkArith() {
public final double checkArith() {
return toDouble();
}

@Override
public final String checkString() {
return toString();
}
}
30 changes: 30 additions & 0 deletions src/main/java/org/squiddev/cobalt/LuaState.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@
import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.lib.platform.FileResourceManipulator;
import org.squiddev.cobalt.lib.platform.ResourceManipulator;
import org.squiddev.cobalt.persist.Serializer;

import java.io.InputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.Executor;
Expand Down Expand Up @@ -134,6 +137,9 @@ public final class LuaState {
*/
boolean abandoned;

private final Map<String, Serializer<?>> serializers = new HashMap<>();
private final Map<String, Object> permanent = new HashMap<>();

public LuaState() {
this(new LuaState.Builder());
}
Expand Down Expand Up @@ -201,6 +207,30 @@ public void setupThread(LuaTable environment) {
currentThread = thread;
}

public void addSerializer(Serializer<?> serializer) {
String name = serializer.getName();
Serializer<?> current = serializers.get(name);
if (serializer == current) return;
if (current != null) throw new IllegalArgumentException("Duplicate serializers for " + name);
serializers.put(name, serializer);
}

public Serializer<?> getSerializer(String name) {
return serializers.get(name);
}

public void addPermanent(String key, Object value) {
Object current = permanent.get(key);
if (value == current) return;
// TODO: Do we want this
// if (current != null) throw new IllegalArgumentException("Duplicate object for " + key);
permanent.put(key, value);
}

public Object getPermanent(String name) {
return permanent.get(name);
}

public static LuaState.Builder builder() {
return new LuaState.Builder();
}
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/squiddev/cobalt/LuaThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
import org.squiddev.cobalt.function.LuaFunction;
import org.squiddev.cobalt.lib.CoroutineLib;
import org.squiddev.cobalt.lib.jse.JsePlatform;
import org.squiddev.cobalt.persist.ValueReader;
import org.squiddev.cobalt.persist.ValueWriter;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -674,6 +677,22 @@ static class State {
}
}

public void writeInternalState(ValueWriter writer) throws IOException {
if (function != null && state.status == STATUS_RUNNING) {
throw new IOException("Cannot serialize running coroutine");
}
if (state.needsThreadedResume) throw new IOException("Cannot serialize coroutine which needs threaded resume");
if (state.javaCount != 0) throw new IOException("Cannot serialize coroutine with Java functions on stack");
writer.writeVarInt(state.status);
writer.write(state.previousThread == null ? Constants.NIL : state.previousThread);
}

public void readInternalState(ValueReader reader) throws IOException {
state.status = reader.readVarInt();
LuaValue previous = (LuaValue) reader.read();
state.previousThread = previous.isNil() ? null : (LuaThread) previous;
}

/**
* Used inside {@link #loop(LuaState, LuaThread, LuaFunction, Varargs)} when
* this particular thread has transferred control elsewhere.
Expand Down
3 changes: 0 additions & 3 deletions src/main/java/org/squiddev/cobalt/debug/DebugHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ public static DebugState getDebugState(LuaState state) {
return state.getCurrentThread().getDebugState();
}

protected DebugHandler() {
}

/**
* Called by Closures and recurring Java functions on return
*
Expand Down
118 changes: 113 additions & 5 deletions src/main/java/org/squiddev/cobalt/debug/DebugState.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
*/
package org.squiddev.cobalt.debug;

import org.squiddev.cobalt.LuaError;
import org.squiddev.cobalt.LuaState;
import org.squiddev.cobalt.UnwindThrowable;
import org.squiddev.cobalt.*;
import org.squiddev.cobalt.function.LuaClosure;
import org.squiddev.cobalt.function.LuaFunction;
import org.squiddev.cobalt.function.Upvalue;
import org.squiddev.cobalt.persist.ValueReader;
import org.squiddev.cobalt.persist.ValueWriter;

import java.io.IOException;

import static org.squiddev.cobalt.debug.DebugFrame.*;

Expand Down Expand Up @@ -104,9 +108,9 @@ public LuaState getLuaState() {
/**
* Push a new debug frame onto the stack, marking it as also consuming one or more Java stack frames.
*
* @return The created info. This should be marked with {@link DebugFrame#FLAG_JAVA} or {
* @return The created info. This should be marked with {@link DebugFrame#FLAG_JAVA} or
* {@link DebugFrame#FLAG_FRESH} by the calling function.
* @throws LuaError On a stack overflow
* @link DebugFrame#FLAG_FRESH} by the calling function.
*/
public DebugFrame pushJavaInfo() throws LuaError {
int javaTop = this.javaCount + 1;
Expand Down Expand Up @@ -272,4 +276,108 @@ void hookLine(DebugFrame frame, int newLine) throws LuaError, UnwindThrowable {
inhook = false;
frame.flags &= ~FLAG_HOOKED;
}

public int getTop() {
return top;
}

private static final int HOOK_CALL = 1 << 0;
private static final int HOOK_RETURN = 1 << 1;
private static final int HOOK_LINE = 1 << 2;

public void writeInternalState(ValueWriter writer) throws IOException {
if (hookfunc instanceof LuaValue) {
writer.write((LuaValue) hookfunc);
writer.writeByte((hookcall ? HOOK_CALL : 0)
| (hookrtrn ? HOOK_RETURN : 0)
| (hookline ? HOOK_LINE : 0));
writer.writeVarInt(hookcount);
writer.writeVarInt(hookcodes);
} else {
writer.write(Constants.NIL);
}

writer.writeVarInt(javaCount);

// Call stack
writer.writeVarInt(top);
for (int i = 0; i <= top; i++) {
DebugFrame frame = stack[i];
assert frame != null;

writer.write(frame.func);
writer.writeVarInt(frame.flags);

writer.writeByte(frame.closure == null ? 0 : 1);
if (frame.closure != null) {
writer.write(frame.stack);
if (frame.stackUpvalues != null) {
for (int j = 0; j < frame.stack.length; j++) {
Upvalue u = frame.stackUpvalues[j];
if (u == null) continue;
writer.writeVarInt(j);
writer.write(u);
}
}
writer.writeVarInt(-1);

writer.write(frame.varargs);
writer.write(frame.extras);
writer.writeVarInt(frame.pc);
writer.writeVarInt(frame.oldPc);
writer.writeVarInt(frame.top);
} else if (frame.state == null) {
writer.write(Constants.NIL);
} else {
writer.serialize(frame.state);
}
}
}

public void readInternalState(ValueReader reader) throws IOException {
// Debug functions
LuaValue hook = (LuaValue) reader.read();
if (!hook.isNil()) {
hookfunc = (LuaFunction) hook;
int state = reader.readByte();
hookcall = (state & HOOK_CALL) != 0;
hookrtrn = (state & HOOK_RETURN) != 0;
hookline = (state & HOOK_LINE) != 0;

hookcount = reader.readVarInt();
hookcodes = reader.readVarInt();
}

javaCount = reader.readVarInt();

// Call stack
top = reader.readVarInt();
stack = new DebugFrame[top + 1];
for (int i = 0; i <= top; i++) {
DebugFrame frame = stack[i] = new DebugFrame(i > 0 ? stack[i - 1] : null);

frame.func = (LuaFunction) reader.read();
frame.flags = reader.readVarInt();
if (reader.readByte() != 0) {
frame.closure = (LuaClosure) frame.func;
frame.stack = (LuaValue[]) reader.read();

frame.stackUpvalues = new Upvalue[frame.stack.length];
while (true) {
int j = reader.readVarInt();
if (j == -1) break;

frame.stackUpvalues[j] = (Upvalue) reader.read();
}

frame.varargs = reader.readVarargs();
frame.extras = reader.readVarargs();
frame.pc = reader.readVarInt();
frame.oldPc = reader.readVarInt();
frame.top = reader.readVarInt();
} else {
frame.state = reader.read();
}
}
}
}
Loading