diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/SystemNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/SystemNativeGenerator.java
index 9b917700c..9a4401d8c 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/SystemNativeGenerator.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/SystemNativeGenerator.java
@@ -36,6 +36,9 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
case "doArrayCopy":
generateArrayCopy(context, writer);
break;
+ case "currentTimeMillis":
+ generateCurrentTimeMillis(writer);
+ break;
}
}
@@ -59,6 +62,10 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
writer.outdent().append("}").softNewLine();
}
+ private void generateCurrentTimeMillis(SourceWriter writer) throws IOException {
+ writer.append("return Long_fromNumber(new Date().getTime());").softNewLine();
+ }
+
private void achieveArrayCopy(DependencyChecker checker, MethodReference method) {
MethodGraph graph = checker.attachMethodGraph(method);
DependencyNode src = graph.getVariableNode(1);
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java
index 61b1c1565..8e3bb6d65 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java
@@ -162,9 +162,9 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
return this;
} else if (TFloat.isInfinite(value)) {
if (value > 0) {
- ensureCapacity(8);
+ ensureCapacity(length + 8);
} else {
- ensureCapacity(9);
+ ensureCapacity(length + 9);
buffer[length++] = '-';
}
buffer[length++] = 'I';
@@ -306,9 +306,9 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
return this;
} else if (TDouble.isInfinite(value)) {
if (value > 0) {
- ensureCapacity(8);
+ ensureCapacity(length + 8);
} else {
- ensureCapacity(9);
+ ensureCapacity(length + 9);
buffer[length++] = '-';
}
buffer[length++] = 'I';
@@ -531,7 +531,7 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
if (start > end || end > s.length() || start < 0) {
throw new TIndexOutOfBoundsException();
}
- ensureCapacity(end - start);
+ ensureCapacity(end - start + length);
for (int i = start; i < end; ++i) {
buffer[length++] = s.charAt(i);
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAppendable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAppendable.java
new file mode 100644
index 000000000..3e28d7388
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAppendable.java
@@ -0,0 +1,30 @@
+/*
+ * 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 org.teavm.classlib.java.io.TIOException;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public interface TAppendable {
+ TAppendable append(TCharSequence csq) throws TIOException;
+
+ TAppendable append(TCharSequence csq, int start, int end) throws TIOException;
+
+ TAppendable append(char c) throws TIOException;
+}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java
index f3e0e8eee..017be86fb 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java
@@ -19,7 +19,7 @@ package org.teavm.classlib.java.lang;
*
* @author Alexey Andreev
*/
-public class TStringBuilder extends TAbstractStringBuilder {
+public class TStringBuilder extends TAbstractStringBuilder implements TAppendable {
public TStringBuilder(int capacity) {
super(capacity);
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystem.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystem.java
index 70e66aafe..7fb6eb876 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystem.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystem.java
@@ -46,4 +46,7 @@ public final class TSystem extends TObject {
@GeneratedBy(SystemNativeGenerator.class)
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
+
+ @GeneratedBy(SystemNativeGenerator.class)
+ public static native long currentTimeMillis();
}
diff --git a/teavm-core/src/main/java/org/teavm/javascript/JavascriptNativeProcessor.java b/teavm-core/src/main/java/org/teavm/javascript/JavascriptNativeProcessor.java
index b40fedb49..2ec035ff5 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/JavascriptNativeProcessor.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/JavascriptNativeProcessor.java
@@ -132,7 +132,7 @@ class JavascriptNativeProcessor {
newInvoke.getArguments().add(invoke.getInstance());
newInvoke.getArguments().add(addStringWrap(addString(method.getName())));
for (int k = 0; k < invoke.getArguments().size(); ++k) {
- Variable arg = wrap(invoke.getArguments().get(k), method.parameterType(k));
+ Variable arg = wrapArgument(invoke.getArguments().get(k), method.parameterType(k));
newInvoke.getArguments().add(arg);
}
replacement.add(newInvoke);
@@ -265,6 +265,34 @@ class JavascriptNativeProcessor {
return result;
}
+ private Variable wrapArgument(Variable var, ValueType type) {
+ if (type instanceof ValueType.Object) {
+ String className = ((ValueType.Object)type).getClassName();
+ ClassHolder cls = classSource.getClassHolder(className);
+ if (cls.getAnnotations().get(JSFunctor.class.getName()) != null) {
+ return wrapFunctor(var, cls);
+ }
+ }
+ return wrap(var, type);
+ }
+
+ private Variable wrapFunctor(Variable var, ClassHolder type) {
+ if (!type.hasModifier(ElementModifier.INTERFACE) || type.getMethods().size() != 1) {
+ throw new RuntimeException("Wrong functor: " + type.getName());
+ }
+ String name = type.getMethods().iterator().next().getName();
+ Variable functor = program.createVariable();
+ Variable nameVar = addString(name);
+ InvokeInstruction insn = new InvokeInstruction();
+ insn.setMethod(new MethodReference(JS.class.getName(), new MethodDescriptor("function",
+ ValueType.object(JSObject.class.getName()), ValueType.object(JSObject.class.getName()),
+ ValueType.object(JSObject.class.getName()))));
+ insn.setReceiver(functor);
+ insn.getArguments().add(var);
+ insn.getArguments().add(nameVar);
+ return functor;
+ }
+
private Variable wrap(Variable var, ValueType type) {
if (type instanceof ValueType.Object) {
String className = ((ValueType.Object)type).getClassName();
diff --git a/teavm-core/src/main/java/org/teavm/javascript/NativeJavascriptClassRepository.java b/teavm-core/src/main/java/org/teavm/javascript/NativeJavascriptClassRepository.java
index 1b69c98b1..43e2635c1 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/NativeJavascriptClassRepository.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/NativeJavascriptClassRepository.java
@@ -1,3 +1,18 @@
+/*
+ * 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.javascript;
import java.util.HashMap;
diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/JS.java b/teavm-core/src/main/java/org/teavm/javascript/ni/JS.java
index c08fcf3b6..d2612de18 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/ni/JS.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/ni/JS.java
@@ -188,4 +188,7 @@ public final class JS {
@InjectedBy(JSNativeGenerator.class)
public static native void set(JSObject instance, JSObject index, JSObject obj);
+
+ @InjectedBy(JSNativeGenerator.class)
+ public static native JSObject function(JSObject instance, JSObject property);
}
diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/JSNativeGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/ni/JSNativeGenerator.java
index 698064309..ca7fba5d4 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/ni/JSNativeGenerator.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/ni/JSNativeGenerator.java
@@ -90,6 +90,9 @@ public class JSNativeGenerator implements Generator, Injector, DependencyPlugin
case "unwrap":
context.writeExpr(context.getArgument(0));
break;
+ case "function":
+ generateFunction(context);
+ break;
}
}
@@ -125,6 +128,18 @@ public class JSNativeGenerator implements Generator, Injector, DependencyPlugin
writer.append("return result;").softNewLine();
}
+ private void generateFunction(InjectorContext context) throws IOException {
+ SourceWriter writer = context.getWriter();
+ writer.append("(function()").ws().append("{").indent().softNewLine();
+ writer.append("return ");
+ context.writeExpr(context.getArgument(1));
+ renderProperty(context.getArgument(2), context);
+ writer.append(".apply(");
+ context.writeExpr(context.getArgument(1));
+ writer.append(",").ws().append("arguments);").softNewLine();
+ writer.outdent().append("})");
+ }
+
private void renderProperty(Expr property, InjectorContext context) throws IOException {
SourceWriter writer = context.getWriter();
String name = extractPropertyName(property);
diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/PreserveOriginalName.java b/teavm-core/src/main/java/org/teavm/javascript/ni/PreserveOriginalName.java
index 5a787aadf..dcc53a109 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/ni/PreserveOriginalName.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/ni/PreserveOriginalName.java
@@ -1,3 +1,18 @@
+/*
+ * 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.javascript.ni;
import java.lang.annotation.ElementType;
diff --git a/teavm-dom/src/main/java/org/teavm/dom/browser/TimerHandler.java b/teavm-dom/src/main/java/org/teavm/dom/browser/TimerHandler.java
new file mode 100644
index 000000000..fa6576cf5
--- /dev/null
+++ b/teavm-dom/src/main/java/org/teavm/dom/browser/TimerHandler.java
@@ -0,0 +1,28 @@
+/*
+ * 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.dom.browser;
+
+import org.teavm.javascript.ni.JSFunctor;
+import org.teavm.javascript.ni.JSObject;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+@JSFunctor
+public interface TimerHandler extends JSObject {
+ void onTimer();
+}
diff --git a/teavm-dom/src/main/java/org/teavm/dom/core/Window.java b/teavm-dom/src/main/java/org/teavm/dom/browser/Window.java
similarity index 77%
rename from teavm-dom/src/main/java/org/teavm/dom/core/Window.java
rename to teavm-dom/src/main/java/org/teavm/dom/browser/Window.java
index 886ad94a8..bff2e1f7e 100644
--- a/teavm-dom/src/main/java/org/teavm/dom/core/Window.java
+++ b/teavm-dom/src/main/java/org/teavm/dom/browser/Window.java
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.teavm.dom.core;
+package org.teavm.dom.browser;
+import org.teavm.dom.core.Document;
+import org.teavm.dom.core.Element;
import org.teavm.javascript.ni.JSGlobal;
import org.teavm.javascript.ni.JSObject;
import org.teavm.javascript.ni.JSProperty;
@@ -33,4 +35,12 @@ public interface Window extends JSGlobal {
void alert(JSObject message);
void alert(String message);
+
+ int setTimeout(TimerHandler handler, int delay);
+
+ void clearTimeout(int timeoutId);
+
+ int setInterval(TimerHandler handler, int delay);
+
+ void clearInterval(int timeoutId);
}
diff --git a/teavm-samples/pom.xml b/teavm-samples/pom.xml
index 44aef862b..7d0a7ed4c 100644
--- a/teavm-samples/pom.xml
+++ b/teavm-samples/pom.xml
@@ -51,7 +51,7 @@
- generate-javascript
+ generate-hello
build-javascript
@@ -60,7 +60,20 @@
false
org.teavm.samples.HelloWorld
true
- false
+ ${project.build.directory}/javascript/hello
+
+
+
+ generate-matrix
+
+ build-javascript
+
+ process-classes
+
+ false
+ org.teavm.samples.MatrixMultiplication
+ true
+ ${project.build.directory}/javascript/matrix
diff --git a/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java
index 077886832..dc0236720 100644
--- a/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java
+++ b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java
@@ -15,9 +15,9 @@
*/
package org.teavm.samples;
+import org.teavm.dom.browser.Window;
import org.teavm.dom.core.Document;
import org.teavm.dom.core.Element;
-import org.teavm.dom.core.Window;
import org.teavm.dom.events.Event;
import org.teavm.dom.events.EventListener;
import org.teavm.dom.events.EventTarget;
diff --git a/teavm-samples/src/main/java/org/teavm/samples/Matrix.java b/teavm-samples/src/main/java/org/teavm/samples/Matrix.java
new file mode 100644
index 000000000..650baca5e
--- /dev/null
+++ b/teavm-samples/src/main/java/org/teavm/samples/Matrix.java
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+// This file is based on the original source code from Bck2Brwsr
+/**
+ * Back 2 Browser Bytecode Translator
+ * Copyright (C) 2012 Jaroslav Tulach
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. Look for COPYING file in the top folder.
+ * If not, see http://opensource.org/licenses/GPL-2.0.
+ */
+package org.teavm.samples;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class Matrix {
+ private final int rank;
+ private final float data[][];
+
+ public Matrix(int r) {
+ this(r, new float[r][r]);
+ }
+
+ private Matrix(int r, float[][] data) {
+ this.rank = r;
+ this.data = data;
+ }
+
+ public void setElement(int i, int j, float value) {
+ data[i][j] = value;
+ }
+ public float getElement(int i, int j) {
+ return data[i][j];
+ }
+
+ public void generateData() {
+ //final Random rand = new Random();
+ //final int x = 10;
+ for (int i = 0; i < rank; i++) {
+ for (int j = 0; j < rank; j++) {
+ data[i][j] = 1 / (1 + i + j);
+ }
+ }
+ }
+
+ public Matrix multiply(Matrix m) {
+ if (rank != m.rank) {
+ throw new IllegalArgumentException("Rank doesn't match");
+ }
+
+ final float res[][] = new float[rank][rank];
+ for (int i = 0; i < rank; i++) {
+ for (int j = 0; j < rank; j++) {
+ float ij = 0;
+ for (int q = 0; q < rank; q++) {
+ ij += data[i][q] * m.data[q][j];
+ }
+ res[i][j] = ij;
+ }
+ }
+ return new Matrix(rank, res);
+ }
+
+ public void printOn(Appendable s) throws IOException {
+ for (int i = 0; i < rank; i++) {
+ String sep = "";
+ for (int j = 0; j < rank; j++) {
+ s.append(sep + data[i][j]);
+ sep = " ";
+ }
+ s.append("\n");
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Matrix) {
+ Matrix snd = (Matrix)obj;
+ if (snd.rank != rank) {
+ return false;
+ }
+ for (int i = 0; i < rank; i++) {
+ for (int j = 0; j < rank; j++) {
+ if (data[i][j] != snd.data[i][j]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 97 * hash + this.rank;
+ hash = 97 * hash + Arrays.deepHashCode(this.data);
+ return hash;
+ }
+}
diff --git a/teavm-samples/src/main/java/org/teavm/samples/MatrixMultiplication.java b/teavm-samples/src/main/java/org/teavm/samples/MatrixMultiplication.java
new file mode 100644
index 000000000..5f917be4a
--- /dev/null
+++ b/teavm-samples/src/main/java/org/teavm/samples/MatrixMultiplication.java
@@ -0,0 +1,47 @@
+/*
+ * 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.samples;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class MatrixMultiplication {
+ public static void main(String[] args) throws IOException {
+ for (int k = 0; k < 100; ++k) {
+ long startTime = System.currentTimeMillis();
+
+ Matrix m1 = new Matrix(5);
+ Matrix m2 = new Matrix(5);
+
+ m1.generateData();
+ m2.generateData();
+
+ Matrix res = null;
+ for (int i = 0; i < 10000; i++) {
+ res = m1.multiply(m2);
+ m1 = res;
+ }
+ StringBuilder sb = new StringBuilder();
+ res.printOn(sb);
+ long timeSpent = System.currentTimeMillis() - startTime;
+ System.out.println(sb.toString());
+ System.out.println("Time spent: " + timeSpent);
+ }
+ }
+}