mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 00:14:10 -08:00
Complete program IO. Add caching of classes on disk
This commit is contained in:
parent
aa9a042360
commit
31204491fc
76
teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java
vendored
Normal file
76
teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.cache;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class DiskCachedClassHolderSource implements ClassHolderSource {
|
||||||
|
private File directory;
|
||||||
|
private ClassHolderSource innerSource;
|
||||||
|
private Map<String, Item> cache = new HashMap<>();
|
||||||
|
private Set<String> newClasses = new HashSet<>();
|
||||||
|
|
||||||
|
public DiskCachedClassHolderSource(File directory, ClassHolderSource innerSource) {
|
||||||
|
this.directory = directory;
|
||||||
|
this.innerSource = innerSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassHolder get(String name) {
|
||||||
|
Item item = cache.get(name);
|
||||||
|
if (item == null) {
|
||||||
|
item = new Item();
|
||||||
|
cache.put(name, item);
|
||||||
|
File classDir = new File(directory, name);
|
||||||
|
}
|
||||||
|
return item.cls;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Item {
|
||||||
|
ClassHolder cls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeClass(OutputStream stream, ClassHolder cls) throws IOException {
|
||||||
|
DataOutput output = new DataOutputStream(stream);
|
||||||
|
output.writeByte(cls.getLevel().ordinal());
|
||||||
|
if (cls.getParent() != null) {
|
||||||
|
output.writeByte(1);
|
||||||
|
output.writeUTF(cls.getParent());
|
||||||
|
} else {
|
||||||
|
output.writeByte(0);
|
||||||
|
}
|
||||||
|
if (cls.getOwnerName() != null) {
|
||||||
|
output.writeByte(1);
|
||||||
|
output.writeUTF(cls.getOwnerName());
|
||||||
|
} else {
|
||||||
|
output.writeByte(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ public class ProgramIO {
|
||||||
private static CastIntegerDirection[] castIntegerDirections = CastIntegerDirection.values();
|
private static CastIntegerDirection[] castIntegerDirections = CastIntegerDirection.values();
|
||||||
private static BranchingCondition[] branchingConditions = BranchingCondition.values();
|
private static BranchingCondition[] branchingConditions = BranchingCondition.values();
|
||||||
private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.values();
|
private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.values();
|
||||||
|
private static ArrayElementType[] arrayElementTypes = ArrayElementType.values();
|
||||||
|
|
||||||
public ProgramIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
public ProgramIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
||||||
this.symbolTable = symbolTable;
|
this.symbolTable = symbolTable;
|
||||||
|
@ -539,10 +540,10 @@ public class ProgramIO {
|
||||||
try {
|
try {
|
||||||
switch (insn.getType()) {
|
switch (insn.getType()) {
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
output.write(insn.getInstance() == null ? 32 : 33);
|
output.write(insn.getInstance() == null ? 33 : 34);
|
||||||
break;
|
break;
|
||||||
case VIRTUAL:
|
case VIRTUAL:
|
||||||
output.write(34);
|
output.write(35);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
output.writeShort(insn.getReceiver() != null ? insn.getReceiver().getIndex() : -1);
|
output.writeShort(insn.getReceiver() != null ? insn.getReceiver().getIndex() : -1);
|
||||||
|
@ -561,8 +562,9 @@ public class ProgramIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(IsInstanceInstruction insn) {
|
public void visit(IsInstanceInstruction insn) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(35);
|
output.writeByte(36);
|
||||||
output.writeShort(insn.getReceiver().getIndex());
|
output.writeShort(insn.getReceiver().getIndex());
|
||||||
|
output.writeInt(symbolTable.lookup(insn.getType().toString()));
|
||||||
output.writeShort(insn.getValue().getIndex());
|
output.writeShort(insn.getValue().getIndex());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -572,7 +574,7 @@ public class ProgramIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(InitClassInstruction insn) {
|
public void visit(InitClassInstruction insn) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(36);
|
output.writeByte(37);
|
||||||
output.writeInt(symbolTable.lookup(insn.getClassName()));
|
output.writeInt(symbolTable.lookup(insn.getClassName()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -582,7 +584,7 @@ public class ProgramIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(NullCheckInstruction insn) {
|
public void visit(NullCheckInstruction insn) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(37);
|
output.writeByte(38);
|
||||||
output.writeShort(insn.getReceiver().getIndex());
|
output.writeShort(insn.getReceiver().getIndex());
|
||||||
output.writeShort(insn.getValue().getIndex());
|
output.writeShort(insn.getValue().getIndex());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -746,8 +748,146 @@ public class ProgramIO {
|
||||||
insn.setSize(program.variableAt(input.readShort()));
|
insn.setSize(program.variableAt(input.readShort()));
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
case 22: {
|
||||||
|
ConstructInstruction insn = new ConstructInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setType(symbolTable.at(input.readInt()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 23: {
|
||||||
|
ConstructMultiArrayInstruction insn = new ConstructMultiArrayInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setItemType(ValueType.parse(symbolTable.at(input.readInt())));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 24: {
|
||||||
|
GetFieldInstruction insn = new GetFieldInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setInstance(program.variableAt(input.readShort()));
|
||||||
|
insn.setField(parseFieldReference(symbolTable.at(input.readInt())));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 25: {
|
||||||
|
GetFieldInstruction insn = new GetFieldInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setField(parseFieldReference(symbolTable.at(input.readInt())));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 26: {
|
||||||
|
PutFieldInstruction insn = new PutFieldInstruction();
|
||||||
|
insn.setInstance(program.variableAt(input.readShort()));
|
||||||
|
insn.setField(parseFieldReference(symbolTable.at(input.readInt())));
|
||||||
|
insn.setValue(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 27: {
|
||||||
|
PutFieldInstruction insn = new PutFieldInstruction();
|
||||||
|
insn.setField(parseFieldReference(symbolTable.at(input.readInt())));
|
||||||
|
insn.setValue(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 28: {
|
||||||
|
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setArray(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 29: {
|
||||||
|
CloneArrayInstruction insn = new CloneArrayInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setArray(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 30: {
|
||||||
|
Variable receiver = program.variableAt(input.readShort());
|
||||||
|
UnwrapArrayInstruction insn = new UnwrapArrayInstruction(arrayElementTypes[input.readByte()]);
|
||||||
|
insn.setReceiver(receiver);
|
||||||
|
insn.setArray(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 31: {
|
||||||
|
GetElementInstruction insn = new GetElementInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setArray(program.variableAt(input.readShort()));
|
||||||
|
insn.setIndex(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 32: {
|
||||||
|
PutElementInstruction insn = new PutElementInstruction();
|
||||||
|
insn.setArray(program.variableAt(input.readShort()));
|
||||||
|
insn.setIndex(program.variableAt(input.readShort()));
|
||||||
|
insn.setValue(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 33: {
|
||||||
|
InvokeInstruction insn = new InvokeInstruction();
|
||||||
|
insn.setType(InvocationType.SPECIAL);
|
||||||
|
int receiverIndex = input.readShort();
|
||||||
|
insn.setReceiver(receiverIndex >= 0 ? program.variableAt(receiverIndex) : null);
|
||||||
|
insn.setMethod(parseMethodReference(symbolTable.at(input.readInt())));
|
||||||
|
int paramCount = insn.getMethod().getDescriptor().parameterCount();
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
insn.getArguments().add(program.variableAt(input.readShort()));
|
||||||
|
}
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 34: {
|
||||||
|
InvokeInstruction insn = new InvokeInstruction();
|
||||||
|
insn.setType(InvocationType.SPECIAL);
|
||||||
|
int receiverIndex = input.readShort();
|
||||||
|
insn.setReceiver(receiverIndex >= 0 ? program.variableAt(receiverIndex) : null);
|
||||||
|
insn.setInstance(program.variableAt(input.readShort()));
|
||||||
|
insn.setMethod(parseMethodReference(symbolTable.at(input.readInt())));
|
||||||
|
int paramCount = insn.getMethod().getDescriptor().parameterCount();
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
insn.getArguments().add(program.variableAt(input.readShort()));
|
||||||
|
}
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 35: {
|
||||||
|
InvokeInstruction insn = new InvokeInstruction();
|
||||||
|
insn.setType(InvocationType.VIRTUAL);
|
||||||
|
int receiverIndex = input.readShort();
|
||||||
|
insn.setReceiver(receiverIndex >= 0 ? program.variableAt(receiverIndex) : null);
|
||||||
|
insn.setInstance(program.variableAt(input.readShort()));
|
||||||
|
insn.setMethod(parseMethodReference(symbolTable.at(input.readInt())));
|
||||||
|
int paramCount = insn.getMethod().getDescriptor().parameterCount();
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
insn.getArguments().add(program.variableAt(input.readShort()));
|
||||||
|
}
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 36: {
|
||||||
|
IsInstanceInstruction insn = new IsInstanceInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setType(ValueType.parse(symbolTable.at(input.readInt())));
|
||||||
|
insn.setValue(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 37: {
|
||||||
|
InitClassInstruction insn = new InitClassInstruction();
|
||||||
|
insn.setClassName(symbolTable.at(input.readInt()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
case 38: {
|
||||||
|
NullCheckInstruction insn = new NullCheckInstruction();
|
||||||
|
insn.setReceiver(program.variableAt(input.readShort()));
|
||||||
|
insn.setValue(program.variableAt(input.readShort()));
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown instruction type: " + insnType);
|
throw new RuntimeException("Unknown instruction type: " + insnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FieldReference parseFieldReference(String text) {
|
||||||
|
int nameIndex = text.lastIndexOf('.');
|
||||||
|
return new FieldReference(text.substring(0, nameIndex), text.substring(nameIndex + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodReference parseMethodReference(String text) {
|
||||||
|
int descIndex = text.lastIndexOf('.');
|
||||||
|
return new MethodReference(text.substring(0, descIndex),
|
||||||
|
MethodDescriptor.parse(text.substring(descIndex) + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user