Implements Double.parseDouble. Fixes bugs. Disabled devirtualization

optimization due to bugs
This commit is contained in:
konsoletyper 2014-02-27 16:06:22 +04:00
parent b4347b4eb8
commit 5c613d2f7f
9 changed files with 251 additions and 10 deletions

View File

@ -22,7 +22,9 @@ import org.teavm.javascript.ni.Rename;
*
* @author Alexey Andreev
*/
public class TDouble extends TNumber {
public class TDouble extends TNumber implements TComparable<TDouble> {
public static double POSITIVE_INFINITY = 1 / 0.0;
public static double NEGATIVE_INFINITY = -POSITIVE_INFINITY;
private double value;
public TDouble(double value) {
@ -57,6 +59,123 @@ public class TDouble extends TNumber {
return TString.wrap(new TStringBuilder().append(d).toString());
}
public static TDouble valueOf(TString string) {
return valueOf(parseDouble(string));
}
public static double parseDouble(TString string) throws TNumberFormatException {
// TODO: parse infinite and different radix
string = string.trim();
boolean negative = false;
int index = 0;
if (string.charAt(index) == '-') {
++index;
negative = true;
} else if (string.charAt(index) == '+') {
++index;
}
char c = string.charAt(index);
if (c < '0' || c > '9') {
throw new TNumberFormatException();
}
long mantissa = 0;
int exp = 0;
while (string.charAt(index) == '0') {
if (++index == string.length()) {
return 0;
}
}
while (index < string.length()) {
c = string.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < 1E17) {
mantissa = mantissa * 10 + (c - '0');
} else {
++exp;
}
++index;
}
if (index < string.length() && string.charAt(index) == '.') {
++index;
boolean hasOneDigit = false;
while (index < string.length()) {
c = string.charAt(index);
if (c < '0' || c > '9') {
break;
}
if (mantissa < 1E17) {
mantissa = mantissa * 10 + (c - '0');
--exp;
}
++index;
hasOneDigit = true;
}
if (!hasOneDigit) {
throw new TNumberFormatException();
}
}
if (index < string.length()) {
c = string.charAt(index);
if (c != 'e' && c != 'E') {
throw new TNumberFormatException();
}
++index;
boolean negativeExp = false;
if (string.charAt(index) == '-') {
++index;
negativeExp = true;
} else if (string.charAt(index) == '+') {
++index;
}
int numExp = 0;
boolean hasOneDigit = false;
while (index < string.length()) {
c = string.charAt(index);
if (c < '0' || c > '9') {
break;
}
numExp = 10 * numExp + (c - '0');
hasOneDigit = true;
++index;
}
if (!hasOneDigit) {
throw new TNumberFormatException();
}
if (negativeExp) {
numExp = -numExp;
}
exp += numExp;
}
if (exp > 308 || exp == 308 && mantissa > 17976931348623157L) {
return !negative ? POSITIVE_INFINITY : NEGATIVE_INFINITY;
}
if (negative) {
mantissa = -mantissa;
}
return mantissa * decimalExponent(exp);
}
private static double decimalExponent(int n) {
double d;
if (n < 0) {
d = 0.1;
n = -n;
} else {
d = 10;
}
double result = 1;
while (n != 0) {
if (n % 2 != 0) {
result *= d;
}
d *= d;
n /= 2;
}
return result;
}
@Override
@Rename("toString")
public TString toString0() {
@ -71,6 +190,15 @@ public class TDouble extends TNumber {
return other instanceof TDouble && ((TDouble)other).value == value;
}
public static int compare(double a, double b) {
return a > b ? 1 : a < b ? -1 : 0;
}
@Override
public int compareTo(TDouble other) {
return compare(value, other.value);
}
@GeneratedBy(DoubleNativeGenerator.class)
public static native boolean isNaN(double v);

View File

@ -38,4 +38,24 @@ public final class TMath extends TObject {
public static long max(long a, long b) {
return a > b ? a : b;
}
public static double min(double a, double b) {
return a < b ? a : b;
}
public static double max(double a, double b) {
return a > b ? a : b;
}
public static int abs(int n) {
return n > 0 ? n : -n;
}
public static long abs(long n) {
return n > 0 ? n : -n;
}
public static double abs(double n) {
return n > 0 ? n : -n;
}
}

View File

@ -219,6 +219,9 @@ public class TArrays extends TObject {
@SuppressWarnings("unchecked")
public static <T> void sort(T[] a, TComparator<? super T> c) {
if (a.length == 0) {
return;
}
Object[] first = a;
Object[] second = new Object[a.length];
int chunkSize = 1;

View File

@ -0,0 +1,26 @@
/*
* 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.classlib.java.util.concurrent;
import org.teavm.classlib.java.lang.TRunnable;
/**
*
* @author Alexey Andreev
*/
public interface TExecutor {
void execute(TRunnable command);
}

View File

@ -0,0 +1,51 @@
/*
* 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.classlib.java.lang;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
public class DoubleTest {
@Test
public void parsed() {
assertEquals(23, Double.parseDouble("23"), 1E-12);
assertEquals(23, Double.parseDouble("23.0"), 1E-12);
assertEquals(23, Double.parseDouble("23E0"), 1E-12);
assertEquals(23, Double.parseDouble("2.30000E1"), 1E-12);
assertEquals(23, Double.parseDouble("0.23E2"), 1E-12);
assertEquals(23, Double.parseDouble("0.000023E6"), 1E-12);
assertEquals(23, Double.parseDouble("00230000e-4"), 1E-12);
assertEquals(23, Double.parseDouble("2300000000000000000000e-20"), 1E-12);
assertEquals(23, Double.parseDouble("2300000000000000000000e-20"), 1E-12);
}
@Test
public void negativeParsed() {
assertEquals(-23, Double.parseDouble("-23"), 1E-12);
}
@Test
public void zeroParsed() {
assertEquals(0, Double.parseDouble("0.0"), 1E-12);
assertEquals(0, Double.parseDouble("23E-8000"), 1E-12);
assertEquals(0, Double.parseDouble("00000"), 1E-12);
assertEquals(0, Double.parseDouble("00000.0000"), 1E-12);
}
}

View File

@ -158,8 +158,8 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
Linker linker = new Linker(dependencyChecker);
ListableClassHolderSource classSet = linker.link(classSource);
Decompiler decompiler = new Decompiler(classSet, classLoader, executor);
devirtualize(classSet, dependencyChecker);
executor.complete();
/*devirtualize(classSet, dependencyChecker);
executor.complete();*/
ClassSetOptimizer optimizer = new ClassSetOptimizer(executor);
optimizer.optimizeAll(classSet);
executor.complete();
@ -198,6 +198,8 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
}
}
// TODO: repair devirtualization
@SuppressWarnings("unused")
private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) {
final Devirtualization devirtualization = new Devirtualization(dependency, classes);
for (String className : classes.getClassNames()) {

View File

@ -1274,11 +1274,9 @@ public class Renderer implements ExprVisitor, StatementVisitor {
.appendClass(catchClause.getExceptionType());
}
writer.append(")").ws().append("{").indent().softNewLine();
if (statement.getExceptionVariable() != catchClause.getExceptionVariable()) {
if (catchClause.getExceptionVariable() != null) {
writer.append(variableName(catchClause.getExceptionVariable())).ws().append("=").ws()
.append("$e;").softNewLine();
}
.append("$je;").softNewLine();
}
for (Statement part : catchClause.getHandler()) {
part.acceptVisitor(this);

View File

@ -89,6 +89,15 @@ public class ProgramParser {
program.basicBlockAt(0).getInstructions().add(insn);
doAnalyze(method);
assemble();
for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock block = program.basicBlockAt(i);
for (int j = 0; j < block.getTryCatchBlocks().size(); ++j) {
TryCatchBlock tryCatch = block.getTryCatchBlocks().get(j);
if (tryCatch.getHandler() == block) {
block.getTryCatchBlocks().remove(j--);
}
}
}
return program;
}

View File

@ -228,8 +228,12 @@ $rt_init = function(cls, constructor, args) {
return obj;
}
$rt_throw = function(ex) {
var err = ex.$jsException;
if (!err) {
var err = new Error("Java exception thrown");
err.$javaException = ex;
ex.$jsException = err;
}
throw err;
}
$rt_byteToInt = function(value) {