mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -08:00
Add statement reader
This commit is contained in:
parent
04d1c28df0
commit
f1249be6dc
220
teavm-core/src/main/java/org/teavm/cache/AstIO.java
vendored
220
teavm-core/src/main/java/org/teavm/cache/AstIO.java
vendored
|
@ -15,11 +15,12 @@
|
|||
*/
|
||||
package org.teavm.cache;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import org.teavm.javascript.ast.*;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
/**
|
||||
|
@ -27,10 +28,13 @@ import org.teavm.model.ValueType;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public class AstIO {
|
||||
private static NodeModifier[] nodeModifiers = NodeModifier.values();
|
||||
private static BinaryOperation[] binaryOperations = BinaryOperation.values();
|
||||
private static UnaryOperation[] unaryOperations = UnaryOperation.values();
|
||||
private SymbolTable symbolTable;
|
||||
private SymbolTable fileTable;
|
||||
private Map<String, IdentifiedStatement> statementMap = new HashMap<>();
|
||||
private IdentifiedStatement lastStatement;
|
||||
|
||||
public AstIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
||||
this.symbolTable = symbolTable;
|
||||
|
@ -45,11 +49,12 @@ public class AstIO {
|
|||
}
|
||||
output.writeShort(method.getParameterDebugNames().size());
|
||||
for (Set<String> debugNames : method.getParameterDebugNames()) {
|
||||
output.writeShort(debugNames.size());
|
||||
output.writeShort(debugNames != null ? debugNames.size() : 0);
|
||||
for (String debugName : debugNames) {
|
||||
output.writeUTF(debugName);
|
||||
}
|
||||
}
|
||||
output.writeBoolean(method.isOriginalNamePreserved());
|
||||
try {
|
||||
method.getBody().acceptVisitor(new NodeWriter(output));
|
||||
} catch (IOExceptionWrapper e) {
|
||||
|
@ -57,6 +62,27 @@ public class AstIO {
|
|||
}
|
||||
}
|
||||
|
||||
public RegularMethodNode read(DataInput input, MethodReference method) throws IOException {
|
||||
RegularMethodNode node = new RegularMethodNode(method);
|
||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
||||
int varCount = input.readShort();
|
||||
for (int i = 0; i < varCount; ++i) {
|
||||
node.getVariables().add((int)input.readShort());
|
||||
}
|
||||
int paramDebugNameCount = input.readShort();
|
||||
for (int i = 0; i < paramDebugNameCount; ++i) {
|
||||
int debugNameCount = input.readShort();
|
||||
Set<String> debugNames = new HashSet<>();
|
||||
for (int j = 0; j < debugNameCount; ++j) {
|
||||
debugNames.add(input.readUTF());
|
||||
}
|
||||
node.getParameterDebugNames().add(debugNames);
|
||||
}
|
||||
node.setOriginalNamePreserved(input.readBoolean());
|
||||
node.setBody(readStatement(input));
|
||||
return node;
|
||||
}
|
||||
|
||||
private int packModifiers(Set<NodeModifier> modifiers) {
|
||||
int packed = 0;
|
||||
for (NodeModifier modifier : modifiers) {
|
||||
|
@ -65,6 +91,16 @@ public class AstIO {
|
|||
return packed;
|
||||
}
|
||||
|
||||
private Set<NodeModifier> unpackModifiers(int packed) {
|
||||
EnumSet<NodeModifier> modifiers = EnumSet.noneOf(NodeModifier.class);
|
||||
while (packed != 0) {
|
||||
int shift = Integer.numberOfTrailingZeros(packed);
|
||||
modifiers.add(nodeModifiers[shift]);
|
||||
packed ^= 1 << shift;
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
class NodeWriter implements ExprVisitor, StatementVisitor {
|
||||
private DataOutput output;
|
||||
|
||||
|
@ -244,7 +280,7 @@ public class AstIO {
|
|||
try {
|
||||
output.writeByte(15);
|
||||
writeLocation(statement.getLocation());
|
||||
output.writeUTF(statement.getClassName());
|
||||
output.writeInt(symbolTable.lookup(statement.getClassName()));
|
||||
} catch (IOException e) {
|
||||
throw new IOExceptionWrapper(e);
|
||||
}
|
||||
|
@ -459,6 +495,182 @@ public class AstIO {
|
|||
}
|
||||
}
|
||||
|
||||
private NodeLocation readLocation(DataInput input) throws IOException {
|
||||
int fileIndex = input.readShort();
|
||||
if (fileIndex == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return new NodeLocation(fileTable.at(fileIndex), input.readShort());
|
||||
}
|
||||
}
|
||||
|
||||
private Statement readStatement(DataInput input) throws IOException {
|
||||
byte type = input.readByte();
|
||||
switch (type) {
|
||||
case 0: {
|
||||
AssignmentStatement stmt = new AssignmentStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
int debugNameCount = input.readShort();
|
||||
for (int i = 0; i < debugNameCount; ++i) {
|
||||
stmt.getDebugNames().add(input.readUTF());
|
||||
}
|
||||
stmt.setLeftValue(readExpr(input));
|
||||
stmt.setRightValue(readExpr(input));
|
||||
return stmt;
|
||||
}
|
||||
case 1: {
|
||||
AssignmentStatement stmt = new AssignmentStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
int debugNameCount = input.readShort();
|
||||
for (int i = 0; i < debugNameCount; ++i) {
|
||||
stmt.getDebugNames().add(input.readUTF());
|
||||
}
|
||||
stmt.setRightValue(readExpr(input));
|
||||
return stmt;
|
||||
}
|
||||
case 2: {
|
||||
SequentialStatement stmt = new SequentialStatement();
|
||||
readSequence(input, stmt.getSequence());
|
||||
return stmt;
|
||||
}
|
||||
case 3: {
|
||||
ConditionalStatement stmt = new ConditionalStatement();
|
||||
stmt.setCondition(readExpr(input));
|
||||
readSequence(input, stmt.getConsequent());
|
||||
readSequence(input, stmt.getAlternative());
|
||||
return stmt;
|
||||
}
|
||||
case 4: {
|
||||
SwitchStatement stmt = new SwitchStatement();
|
||||
stmt.setId(readNullableString(input));
|
||||
stmt.setValue(readExpr(input));
|
||||
int clauseCount = input.readShort();
|
||||
for (int i = 0; i < clauseCount; ++i) {
|
||||
SwitchClause clause = new SwitchClause();
|
||||
int conditionCount = input.readShort();
|
||||
int[] conditions = new int[conditionCount];
|
||||
for (int j = 0; j < conditionCount; ++j) {
|
||||
conditions[j] = input.readInt();
|
||||
}
|
||||
clause.setConditions(conditions);
|
||||
readSequence(input, clause.getBody());
|
||||
stmt.getClauses().add(clause);
|
||||
}
|
||||
readSequence(input, stmt.getDefaultClause());
|
||||
return stmt;
|
||||
}
|
||||
case 5: {
|
||||
WhileStatement stmt = new WhileStatement();
|
||||
stmt.setId(readNullableString(input));
|
||||
stmt.setCondition(readExpr(input));
|
||||
lastStatement = stmt;
|
||||
if (stmt.getId() != null) {
|
||||
statementMap.put(stmt.getId(), stmt);
|
||||
}
|
||||
readSequence(input, stmt.getBody());
|
||||
return stmt;
|
||||
}
|
||||
case 6: {
|
||||
WhileStatement stmt = new WhileStatement();
|
||||
stmt.setId(readNullableString(input));
|
||||
lastStatement = stmt;
|
||||
if (stmt.getId() != null) {
|
||||
statementMap.put(stmt.getId(), stmt);
|
||||
}
|
||||
readSequence(input, stmt.getBody());
|
||||
return stmt;
|
||||
}
|
||||
case 7: {
|
||||
BlockStatement stmt = new BlockStatement();
|
||||
stmt.setId(readNullableString(input));
|
||||
lastStatement = stmt;
|
||||
if (stmt.getId() != null) {
|
||||
statementMap.put(stmt.getId(), stmt);
|
||||
}
|
||||
readSequence(input, stmt.getBody());
|
||||
return stmt;
|
||||
}
|
||||
case 8: {
|
||||
BreakStatement stmt = new BreakStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setTarget(statementMap.get(input.readUTF()));
|
||||
return stmt;
|
||||
}
|
||||
case 9: {
|
||||
BreakStatement stmt = new BreakStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setTarget(lastStatement);
|
||||
return stmt;
|
||||
}
|
||||
case 10: {
|
||||
ContinueStatement stmt = new ContinueStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setTarget(statementMap.get(input.readUTF()));
|
||||
return stmt;
|
||||
}
|
||||
case 11: {
|
||||
ContinueStatement stmt = new ContinueStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setTarget(lastStatement);
|
||||
return stmt;
|
||||
}
|
||||
case 12: {
|
||||
ReturnStatement stmt = new ReturnStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setResult(readExpr(input));
|
||||
return stmt;
|
||||
}
|
||||
case 13: {
|
||||
ReturnStatement stmt = new ReturnStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
return stmt;
|
||||
}
|
||||
case 14: {
|
||||
ThrowStatement stmt = new ThrowStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setException(readExpr(input));
|
||||
return stmt;
|
||||
}
|
||||
case 15: {
|
||||
InitClassStatement stmt = new InitClassStatement();
|
||||
stmt.setLocation(readLocation(input));
|
||||
stmt.setClassName(symbolTable.at(input.readInt()));
|
||||
return stmt;
|
||||
}
|
||||
case 16: {
|
||||
TryCatchStatement stmt = new TryCatchStatement();
|
||||
readSequence(input, stmt.getProtectedBody());
|
||||
int exceptionTypeIndex = input.readInt();
|
||||
if (exceptionTypeIndex >= 0) {
|
||||
stmt.setExceptionType(symbolTable.at(exceptionTypeIndex));
|
||||
}
|
||||
int exceptionVarIndex = input.readInt();
|
||||
if (exceptionVarIndex >= 0) {
|
||||
stmt.setExceptionVariable(exceptionVarIndex);
|
||||
}
|
||||
readSequence(input, stmt.getHandler());
|
||||
return stmt;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Unexpected statement type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void readSequence(DataInput input, List<Statement> statements) throws IOException {
|
||||
int count = input.readShort();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
statements.add(readStatement(input));
|
||||
}
|
||||
}
|
||||
|
||||
private String readNullableString(DataInput input) throws IOException {
|
||||
return input.readBoolean() ? input.readUTF() : null;
|
||||
}
|
||||
|
||||
private Expr readExpr(DataInput input) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class IOExceptionWrapper extends RuntimeException {
|
||||
private static final long serialVersionUID = -7566355431593608333L;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user