mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 16:04: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 BranchingCondition[] branchingConditions = BranchingCondition.values();
|
||||
private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.values();
|
||||
private static ArrayElementType[] arrayElementTypes = ArrayElementType.values();
|
||||
|
||||
public ProgramIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
||||
this.symbolTable = symbolTable;
|
||||
|
@ -539,10 +540,10 @@ public class ProgramIO {
|
|||
try {
|
||||
switch (insn.getType()) {
|
||||
case SPECIAL:
|
||||
output.write(insn.getInstance() == null ? 32 : 33);
|
||||
output.write(insn.getInstance() == null ? 33 : 34);
|
||||
break;
|
||||
case VIRTUAL:
|
||||
output.write(34);
|
||||
output.write(35);
|
||||
break;
|
||||
}
|
||||
output.writeShort(insn.getReceiver() != null ? insn.getReceiver().getIndex() : -1);
|
||||
|
@ -561,8 +562,9 @@ public class ProgramIO {
|
|||
@Override
|
||||
public void visit(IsInstanceInstruction insn) {
|
||||
try {
|
||||
output.writeByte(35);
|
||||
output.writeByte(36);
|
||||
output.writeShort(insn.getReceiver().getIndex());
|
||||
output.writeInt(symbolTable.lookup(insn.getType().toString()));
|
||||
output.writeShort(insn.getValue().getIndex());
|
||||
} catch (IOException e) {
|
||||
throw new IOExceptionWrapper(e);
|
||||
|
@ -572,7 +574,7 @@ public class ProgramIO {
|
|||
@Override
|
||||
public void visit(InitClassInstruction insn) {
|
||||
try {
|
||||
output.writeByte(36);
|
||||
output.writeByte(37);
|
||||
output.writeInt(symbolTable.lookup(insn.getClassName()));
|
||||
} catch (IOException e) {
|
||||
throw new IOExceptionWrapper(e);
|
||||
|
@ -582,7 +584,7 @@ public class ProgramIO {
|
|||
@Override
|
||||
public void visit(NullCheckInstruction insn) {
|
||||
try {
|
||||
output.writeByte(37);
|
||||
output.writeByte(38);
|
||||
output.writeShort(insn.getReceiver().getIndex());
|
||||
output.writeShort(insn.getValue().getIndex());
|
||||
} catch (IOException e) {
|
||||
|
@ -746,8 +748,146 @@ public class ProgramIO {
|
|||
insn.setSize(program.variableAt(input.readShort()));
|
||||
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:
|
||||
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