Implements some of JVM class library

This commit is contained in:
Alexey Andreev 2013-11-27 10:11:21 +04:00
parent 1355e211e3
commit c244c596c9
8 changed files with 123 additions and 15 deletions

View File

@ -2,24 +2,25 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.lang.io.TSerializable;
import org.teavm.classlib.java.util.TArrays;
import org.teavm.javascript.ni.Rename;
/**
*
* @author Alexey Andreev
*/
class AbstractStringBuilder extends TObject implements TSerializable {
class TAbstractStringBuilder extends TObject implements TSerializable {
private char[] buffer;
private int length;
public AbstractStringBuilder() {
public TAbstractStringBuilder() {
this(16);
}
public AbstractStringBuilder(int capacity) {
public TAbstractStringBuilder(int capacity) {
buffer = new char[capacity];
}
protected AbstractStringBuilder append(TString string) {
protected TAbstractStringBuilder append(TString string) {
ensureCapacity(length + string.length());
int j = length;
for (int i = 0; i < string.length(); ++i) {
@ -29,13 +30,20 @@ class AbstractStringBuilder extends TObject implements TSerializable {
return this;
}
protected AbstractStringBuilder append(int value) {
protected TAbstractStringBuilder append(int value) {
boolean positive = true;
if (value < 0) {
append('-');
positive = false;
value = -value;
}
if (value < 10) {
append((char)('0' + value));
if (!positive) {
ensureCapacity(length + 2);
buffer[length++] = '-';
} else {
ensureCapacity(length + 1);
}
buffer[length++] = (char)('0' + value);
} else {
int pos = 10;
int sz = 1;
@ -43,7 +51,14 @@ class AbstractStringBuilder extends TObject implements TSerializable {
pos *= 10;
++sz;
}
if (!positive) {
++sz;
}
ensureCapacity(length + sz);
if (!positive) {
buffer[length++] = '-';
}
pos /= 10;
while (pos > 0) {
buffer[length++] = (char)('0' + value / pos);
value %= pos;
@ -53,7 +68,7 @@ class AbstractStringBuilder extends TObject implements TSerializable {
return this;
}
protected AbstractStringBuilder append(char c) {
protected TAbstractStringBuilder append(char c) {
ensureCapacity(length + 1);
buffer[length++] = c;
return this;
@ -65,4 +80,10 @@ class AbstractStringBuilder extends TObject implements TSerializable {
}
buffer = TArrays.copyOf(buffer, capacity * 2 + 1);
}
@Override
@Rename("toString")
public TString toString0() {
return new TString(buffer, 0, length);
}
}

View File

@ -0,0 +1,14 @@
package org.teavm.classlib.java.lang;
/**
*
* @author Alexey Andreev
*/
public final class TMath extends TObject {
private TMath() {
}
public static int min(int a, int b) {
return a < b ? a : b;
}
}

View File

@ -9,6 +9,7 @@ import org.teavm.javascript.ni.GeneratedBy;
*/
public class TString extends TObject implements TSerializable {
private char[] characters;
private transient int hashCode;
public TString() {
this.characters = new char[0];
@ -47,6 +48,41 @@ public class TString extends TObject implements TSerializable {
return new TStringBuilder().append(index).toString0();
}
@Override
public boolean equals(TObject other) {
if (this == other) {
return true;
}
if (!(other instanceof TString)) {
return false;
}
TString str = (TString)other;
if (str.length() != length()) {
return false;
}
for (int i = 0; i < str.length(); ++i) {
if (charAt(i) != str.charAt(i)) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode ^= 734262231;
for (char c : characters) {
hashCode = (hashCode << 4) | (hashCode >>> 28);
hashCode ^= 347236277 ^ c;
if (hashCode == 0) {
++hashCode;
}
}
}
return hashCode;
}
@GeneratedBy(StringNativeGenerator.class)
public static native TString wrap(String str);
}

View File

@ -4,7 +4,7 @@ package org.teavm.classlib.java.lang;
*
* @author Alexey Andreev
*/
public class TStringBuilder extends AbstractStringBuilder {
public class TStringBuilder extends TAbstractStringBuilder {
@Override
public TStringBuilder append(TString string) {
super.append(string);

View File

@ -0,0 +1,17 @@
package org.teavm.classlib.java.lang;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
class TStringBuilderTests {
@Test
public void integerAppended() {
TStringBuilder sb = new TStringBuilder();
sb.append(23);
assertEquals("23", sb.toString());
}
}

View File

@ -30,7 +30,8 @@ public class ClasslibTestGenerator {
private static Renderer renderer;
private static List<MethodReference> testMethods = new ArrayList<>();
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests" };
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests",
"java.lang.StringBuilderTests" };
public static void main(String[] args) throws IOException {
out = System.out;

View File

@ -159,10 +159,20 @@ public class DependencyChecker {
}
}
private MethodGraph createMethodGraph(MethodReference methodRef) {
private MethodGraph createMethodGraph(final MethodReference methodRef) {
initClass(methodRef.getClassName());
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
if (method == null) {
while (cls != null) {
method = cls.getMethod(methodRef.getDescriptor());
if (method != null) {
return methodCache.map(new MethodReference(cls.getName(), methodRef.getDescriptor()));
}
cls = classSource.getClassHolder(cls.getParent());
}
throw new RuntimeException("Method not found: " + methodRef);
}
ValueType[] arguments = method.getParameterTypes();
int paramCount = arguments.length + 1;
int varCount = Math.max(paramCount, method.getProgram().variableCount());
@ -184,10 +194,15 @@ public class DependencyChecker {
method.getName() + MethodDescriptor.get(method) + ":RESULT");
}
}
MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(this);
graphBuilder.buildGraph(method, graph);
achieveClass(methodRef.getClassName());
final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
final MethodHolder currentMethod = method;
executor.submit(new Runnable() {
@Override public void run() {
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
graphBuilder.buildGraph(currentMethod, graph);
achieveClass(methodRef.getClassName());
}
});
return graph;
}
@ -223,6 +238,9 @@ public class DependencyChecker {
private void activateDependencyPlugin(MethodReference methodRef) {
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
if (method == null) {
return;
}
AnnotationHolder depAnnot = method.getAnnotations().get(PluggableDependency.class.getName());
if (depAnnot == null) {
return;

View File

@ -98,5 +98,6 @@ public class ClassHolder extends ElementHolder {
field.getName() + " is not a member of " + getName());
}
fields.remove(field.getName());
field.setOwner(null);
}
}