From bb7053cfa4ee33f0e2bffdf17862057b264a26b8 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 6 Dec 2013 17:16:56 +0400 Subject: [PATCH] Improvements --- .../org/teavm/classlib/java/lang/TString.java | 36 +++++- .../org/teavm/classlib/java/lang/VMTests.java | 39 ++++++ .../classlibgen/ClasslibTestGenerator.java | 3 +- .../java/org/teavm/javascript/Renderer.java | 19 ++- .../java/org/teavm/parsing/ProgramParser.java | 1 - .../resources/org/teavm/javascript/runtime.js | 117 ++++++++++-------- 6 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/VMTests.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index b12287de6..0a66d0d8d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -373,10 +373,6 @@ public class TString extends TObject implements TSerializable, TComparable testMethods = new ArrayList<>(); private static Map> groupedMethods = new HashMap<>(); private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests", - "java.lang.StringBuilderTests", "java.lang.ClassTests", "java.lang.StringTests" }; + "java.lang.StringBuilderTests", "java.lang.ClassTests", "java.lang.StringTests", + "java.lang.VMTests" }; public static void main(String[] args) throws IOException { out = System.out; diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 5cc906b79..835949e8e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -89,7 +89,7 @@ public class Renderer implements ExprVisitor, StatementVisitor { MethodReference stringCons = new MethodReference(stringClass, new MethodDescriptor("", ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)); writer.append("$rt_str = function(str) {").indent().newLine(); - writer.append("var characters = $rt_createNumericArray($rt_charcls(), str.length);").newLine(); + writer.append("var characters = $rt_createCharArray(str.length);").newLine(); writer.append("var charsBuffer = characters.data;").newLine(); writer.append("for (var i = 0; i < str.length; i = (i + 1) | 0) {").indent().newLine(); writer.append("charsBuffer[i] = str.charCodeAt(i) & 0xFFFF;").newLine(); @@ -840,22 +840,22 @@ public class Renderer implements ExprVisitor, StatementVisitor { if (type instanceof ValueType.Primitive) { switch (((ValueType.Primitive)type).getKind()) { case BOOLEAN: - writer.append("$rt_createBooleanArray($rt_booleancls(), "); + writer.append("$rt_createBooleanArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; case BYTE: - writer.append("$rt_createNumericArray($rt_bytecls(), "); + writer.append("$rt_createByteArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; case SHORT: - writer.append("$rt_createNumericArray($rt_shortcls(), "); + writer.append("$rt_createShortArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; case INTEGER: - writer.append("$rt_createNumericArray($rt_intcls(), "); + writer.append("$rt_createIntArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; @@ -865,17 +865,17 @@ public class Renderer implements ExprVisitor, StatementVisitor { writer.append(")"); break; case FLOAT: - writer.append("$rt_createNumericArray($rt_floatcls(), "); + writer.append("$rt_createFloatArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; case DOUBLE: - writer.append("$rt_createNumericArray($rt_doublecls(), "); + writer.append("$rt_createDoubleArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; case CHARACTER: - writer.append("$rt_createNumericArray($rt_charcls(), "); + writer.append("$rt_createCharArray("); expr.getLength().acceptVisitor(this); writer.append(")"); break; @@ -889,8 +889,7 @@ public class Renderer implements ExprVisitor, StatementVisitor { @Override public void visit(NewMultiArrayExpr expr) { - writer.append("$rt_createMultiArray(").append(typeToClsString(naming, expr.getType())) - .append(", ["); + writer.append("$rt_createMultiArray(").append(typeToClsString(naming, expr.getType())).append(", ["); boolean first = true; for (Expr dimension : expr.getDimensions()) { if (!first) { diff --git a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java index 3e73985d3..c7a6c10e3 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -331,7 +331,6 @@ public class ProgramParser { Variable[] dimensions = new Variable[dims]; for (int i = dims - 1; i >= 0; --i) { dimensions[i] = getVariable(--currentDepth); - arrayType = ValueType.arrayOf(arrayType); } int var = currentDepth++; ConstructMultiArrayInstruction insn = new ConstructMultiArrayInstruction(); diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 0a35c612c..4e4e29731 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -25,24 +25,62 @@ $rt_createArray = function(cls, sz) { var arr = new ($rt_arraycls(cls))(data); arr.$id = $rt_nextId(); for (var i = 0; i < sz; i = (i + 1) | 0) { - arr.data[i] = null; - } - return arr; -} -$rt_createNumericArray = function(cls, sz) { - var arr = $rt_createArray(cls, sz); - for (var i = 0; i < sz; i = (i + 1) | 0) { - arr.data[i] = 0; + data[i] = null; } return arr; } $rt_createLongArray = function(sz) { - var arr = $rt.createArray($rt_longcls(), sz); + var data = new Array(sz); + var arr = new ($rt_arraycls($rt_longcls()))(data); + arr.$id = $rt_nextId(); for (var i = 0; i < sz; i = (i + 1) | 0) { - arr.data[i] = Long.ZERO; + data[i] = Long.ZERO; } return arr; -}, +} +if (ArrayBuffer) { + $rt_createNumericArray = function(cls, nativeArray) { + return new ($rt_arraycls(cls))(nativeArray); + } + $rt_createByteArray = function(sz) { + return $rt_createNumericArray($rt_bytecls(), new Int8Array(new ArrayBuffer(sz)), 0); + }; + $rt_createShortArray = function(sz) { + return $rt_createNumericArray($rt_shortcls(), new Int16Array(new ArrayBuffer(sz << 1)), 0); + }; + $rt_createIntArray = function(sz) { + return $rt_createNumericArray($rt_intcls(), new Int32Array(new ArrayBuffer(sz << 2)), 0); + }; + $rt_createBooleanArray = function(sz) { + return $rt_createNumericArray($rt_booleancls(), new Int8Array(new ArrayBuffer(sz)), 0); + }; + $rt_createFloatArray = function(sz) { + return $rt_createNumericArray($rt_floatcls(), new Float32Array(new ArrayBuffer(sz << 2)), 0); + }; + $rt_createDoubleArray = function(sz) { + return $rt_createNumericArray($rt_doublecls(), new Float64Array(new ArrayBuffer(sz << 3)), 0); + }; + $rt_createCharArray = function(sz) { + return $rt_createNumericArray($rt_charcls(), new Uint16Array(new ArrayBuffer(sz << 1)), 0); + }; +} else { + $rt_createNumericArray = function(cls, sz) { + var data = new Array(sz); + var arr = new ($rt_arraycls(cls))(data); + arr.$id = $rt_nextId(); + for (var i = 0; i < sz; i = (i + 1) | 0) { + data[i] = 0; + } + return arr; + } + $rt_createByteArray = function(sz) { return $rt_createNumericArray($rt_bytecls(), sz); } + $rt_createShortArray = function(sz) { return $rt_createNumericArray($rt_shortcls(), sz); } + $rt_createIntArray = function(sz) { return $rt_createNumericArray($rt_intcls(), sz); } + $rt_createBooleanArray = function(sz) { return $rt_createNumericArray($rt_booleancls(), sz); } + $rt_createFloatArray = function(sz) { return $rt_createNumericArray($rt_floatcls(), sz); } + $rt_createDoubleArray = function(sz) { return $rt_createNumericArray($rt_doublecls(), sz); } + $rt_createCharArray = function(sz) { return $rt_createNumericArray($rt_charcls(), sz); } +} $rt_arraycls = function(cls) { if (cls.$array == undefined) { var arraycls = function(data) { @@ -180,45 +218,26 @@ $rt_byteToInt = function(value) { $rt_shortToInt = function(value) { return value > 0xFFFF ? value | 0xFFFF0000 : value; } - -$rt = { - createBooleanArray : function(cls, sz) { - var arr = $rt.createArray(cls, sz); - for (var i = 0; i < sz; i = (i + 1) | 0) { - arr[i] = false; +$rt_createMultiArray = function(cls, dimensions) { + return $rt_createMultiArrayImpl(cls, dimensions, 0); +} +$rt_createMultiArrayImpl = function(cls, dimensions, offset) { + cls = cls.$meta.item; + var result = $rt_createArray(cls, dimensions[offset]); + offset = (offset + 1) | 0; + if (offset < dimensions.length) { + for (var i = 0; i < result.data.length; i = (i + 1) | 0) { + result.data[i] = $rt_createMultiArrayImpl(cls, dimensions, offset); } - return arr; - }, - createMultiArray : function(cls, dimensions) { - for (var i = 1; i < dimensions.length; i = (i + 1) | 0) { - cls = $rt.arraycls(cls); - } - return $rt.createMultiArrayImpl(cls, dimensions, 0); - }, - createMultiArrayImpl : function(cls, dimensions, offset) { - var result = $rt.createArray(cls, dimensions[offset]); - offset = (offset + 1) | 0; - if (offset < dimensions.length) { - cls = cls.$meta.item; - for (var i = 0; i < result.length; i = (i + 1) | 0) { - result[i] = $rt.createMultiArrayImpl(cls, dimensions, offset); - } - } - return result; - }, - initializeArray : function(cls, initial) { - var arr = initial.slice(); - arr.$class = $rt.arraycls(cls); - $rt.setId(arr, $rt.lastObjectId++); - return arr; - }, - assertNotNaN : function(value) { - if (typeof value == 'number' && isNaN(value)) { - throw "NaN"; - } - return value; } -}; + return result; +} +$rt_assertNotNaN = function(value) { + if (typeof value == 'number' && isNaN(value)) { + throw "NaN"; + } + return value; +} Long = function(lo, hi) { this.lo = lo | 0; @@ -268,7 +287,7 @@ Long_dec = function(a) { return new Long(lo, hi); } Long_neg = function(a) { - return Long.inc(new Long(a.lo ^ 0xFFFFFFFF, a.hi ^ 0xFFFFFFFF)); + return Long_inc(new Long(a.lo ^ 0xFFFFFFFF, a.hi ^ 0xFFFFFFFF)); } Long_sub = function(a, b) { var a_lolo = a.lo & 0xFFFF;