diff --git a/pom.xml b/pom.xml
index daf2754ca..6008b055e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,6 +16,7 @@
teavm-core
teavm-classlib
teavm-maven-plugin
+ teavm-samples
diff --git a/teavm-classlib/pom.xml b/teavm-classlib/pom.xml
index 031b81162..469280e11 100644
--- a/teavm-classlib/pom.xml
+++ b/teavm-classlib/pom.xml
@@ -20,7 +20,6 @@
org.teavm
teavm-core
${project.version}
- true
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/ByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/ByteBuffer.java
new file mode 100644
index 000000000..07dccaca5
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/ByteBuffer.java
@@ -0,0 +1,55 @@
+package org.teavm.classlib.impl.charset;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class ByteBuffer {
+ private byte[] data;
+ private int end;
+ private int pos;
+
+ public ByteBuffer(byte[] data) {
+ this(data, 0, data.length);
+ }
+
+ public ByteBuffer(byte[] data, int start, int end) {
+ this.data = data;
+ this.end = end;
+ this.pos = start;
+ }
+
+ public void put(byte b) {
+ data[pos++] = b;
+ }
+
+ public void rewind(int start) {
+ this.pos = start;
+ }
+
+ public int available() {
+ return end - pos;
+ }
+
+ public void back(int count) {
+ pos -= count;
+ }
+
+ public boolean end() {
+ return pos == end;
+ }
+
+ public byte get() {
+ return data[pos++];
+ }
+
+ public int position() {
+ return pos;
+ }
+
+ public void put(ByteBuffer buffer) {
+ while (buffer.pos < buffer.end) {
+ data[pos++] = buffer.data[buffer.pos++];
+ }
+ }
+}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java
new file mode 100644
index 000000000..26584c705
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java
@@ -0,0 +1,55 @@
+package org.teavm.classlib.impl.charset;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class CharBuffer {
+ private char[] data;
+ private int end;
+ private int pos;
+
+ public CharBuffer(char[] data, int start, int end) {
+ this.data = data;
+ this.end = end;
+ this.pos = start;
+ }
+
+ public CharBuffer(char[] data) {
+ this(data, 0, data.length);
+ }
+
+ public void put(char b) {
+ data[pos++] = b;
+ }
+
+ public void rewind(int start) {
+ this.pos = start;
+ }
+
+ public int available() {
+ return end - pos;
+ }
+
+ public void back(int count) {
+ pos -= count;
+ }
+
+ public boolean end() {
+ return pos == end;
+ }
+
+ public char get() {
+ return data[pos++];
+ }
+
+ public int position() {
+ return pos;
+ }
+
+ public void put(CharBuffer buffer) {
+ while (buffer.pos < buffer.end) {
+ data[pos++] = buffer.data[buffer.pos++];
+ }
+ }
+}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/Charset.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/Charset.java
index a2963e13a..36de70f28 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/Charset.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/Charset.java
@@ -5,9 +5,14 @@ package org.teavm.classlib.impl.charset;
* @author Alexey Andreev
*/
public abstract class Charset {
- public abstract int encode(int[] buffer, int offset, int length, byte[] dest, int destOffset, int destLength);
+ public abstract void encode(CharBuffer source, ByteBuffer dest);
- public abstract int decode(byte[] buffer, int offset, int length, int[] dest, int destOffset, int destLength);
+ public abstract void decode(ByteBuffer source, CharBuffer dest);
- public static native Charset get(String name);
+ public static Charset get(String name) {
+ if (name.equals("UTF-8")) {
+ return new UTF8Charset();
+ }
+ return null;
+ }
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharsetName.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharsetName.java
deleted file mode 100644
index e8b488cd3..000000000
--- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharsetName.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.teavm.classlib.impl.charset;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- *
- * @author Alexey Andreev
- */
-@Retention(RetentionPolicy.CLASS)
-@Target(ElementType.TYPE)
-public @interface CharsetName {
- String value();
-}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java
index 9396db9da..e1ee06530 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java
@@ -5,10 +5,12 @@ package org.teavm.classlib.impl.charset;
* @author Alexey Andreev
*/
public class UTF16Helper {
+ public static final int SURROGATE_NEUTRAL_BIT_MASK = 0xF800;
+ public static final int SURROGATE_BITS = 0xD800;
public static final int SURROGATE_BIT_MASK = 0xFC00;
public static final int SURROGATE_BIT_INV_MASK = 0x03FF;
- public static final int HIGH_SURROGATE_BITS = 0xF800;
- public static final int LOW_SURROGATE_BITS = 0xF800;
+ public static final int HIGH_SURROGATE_BITS = 0xD800;
+ public static final int LOW_SURROGATE_BITS = 0xDC00;
public static final int MEANINGFUL_SURROGATE_BITS = 10;
public static final int SUPPLEMENTARY_PLANE = 0x10000;
@@ -34,6 +36,10 @@ public class UTF16Helper {
public static int buildCodePoint(char a, char b) {
return ((a & SURROGATE_BIT_INV_MASK) << MEANINGFUL_SURROGATE_BITS) |
- (b & SURROGATE_BIT_INV_MASK) + SUPPLEMENTARY_PLANE;
+ (b & SURROGATE_BIT_INV_MASK) + SUPPLEMENTARY_PLANE;
+ }
+
+ public static boolean isSurrogate(char c) {
+ return (c & SURROGATE_NEUTRAL_BIT_MASK) == SURROGATE_BITS;
}
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF8Charset.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF8Charset.java
index 59b866e69..5a9bc60ec 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF8Charset.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF8Charset.java
@@ -4,15 +4,40 @@ package org.teavm.classlib.impl.charset;
*
* @author Alexey Andreev
*/
-@CharsetName("UTF-8")
public class UTF8Charset extends Charset {
@Override
- public int encode(int[] buffer, int offset, int length, byte[] dest, int destOffset, int destLength) {
- return 0;
+ public void encode(CharBuffer source, ByteBuffer dest) {
+ while (!source.end() && dest.available() >= 4) {
+ char ch = source.get();
+ if (ch < 0x80) {
+ dest.put((byte)ch);
+ } else if (ch < 0x400) {
+ dest.put((byte)(0xC0 | (ch >> 6)));
+ dest.put((byte)(0x80 | (ch & 0x3F)));
+ } else if (!UTF16Helper.isSurrogate(ch)) {
+ dest.put((byte)(0xE0 | (ch >> 12)));
+ dest.put((byte)(0x80 | ((ch >> 6) & 0x3F)));
+ dest.put((byte)(0x80 | (ch & 0x3F)));
+ } else if (UTF16Helper.isHighSurrogate(ch)) {
+ char low = source.get();
+ if (!UTF16Helper.isLowSurrogate(ch)) {
+ source.back(1);
+ dest.put((byte)'?');
+ } else {
+ int codePoint = UTF16Helper.buildCodePoint(ch, low);
+ dest.put((byte)(0xF0 | (codePoint >> 18)));
+ dest.put((byte)(0x80 | ((codePoint >> 12) & 0x3F)));
+ dest.put((byte)(0x80 | ((codePoint >> 6) & 0x3F)));
+ dest.put((byte)(0x80 | (codePoint & 0x3F)));
+ }
+ } else {
+ dest.put((byte)'?');
+ }
+ }
}
@Override
- public int decode(byte[] buffer, int offset, int length, int[] dest, int destOffset, int destLength) {
- return 0;
+ public void decode(ByteBuffer source, CharBuffer dest) {
+
}
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TCloseable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TCloseable.java
similarity index 82%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TCloseable.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TCloseable.java
index 1bc55c48b..102ab7b6b 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TCloseable.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TCloseable.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
import org.teavm.classlib.java.lang.TAutoCloseable;
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFilterOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFilterOutputStream.java
similarity index 93%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFilterOutputStream.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFilterOutputStream.java
index d396f2e20..4a1487eaf 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFilterOutputStream.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFilterOutputStream.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
/**
*
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFlushable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFlushable.java
similarity index 72%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFlushable.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFlushable.java
index a5e8c0a23..5174d7bba 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TFlushable.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TFlushable.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
/**
*
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TIOException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TIOException.java
similarity index 93%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TIOException.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TIOException.java
index e212c3fe0..663b56f97 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TIOException.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TIOException.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
import org.teavm.classlib.java.lang.TException;
import org.teavm.classlib.java.lang.TString;
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TOutputStream.java
similarity index 93%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TOutputStream.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TOutputStream.java
index 5de5e3a57..30a46ed4c 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TOutputStream.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TOutputStream.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
import org.teavm.classlib.java.lang.TObject;
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java
similarity index 65%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java
index 48bcd7d30..1ceba6a99 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java
@@ -1,6 +1,10 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
+import org.teavm.classlib.impl.charset.ByteBuffer;
+import org.teavm.classlib.impl.charset.CharBuffer;
+import org.teavm.classlib.impl.charset.Charset;
import org.teavm.classlib.java.lang.TMath;
+import org.teavm.classlib.java.lang.TString;
import org.teavm.classlib.java.lang.TStringBuilder;
/**
@@ -12,10 +16,21 @@ public class TPrintStream extends TFilterOutputStream {
private boolean errorState;
private TStringBuilder sb = new TStringBuilder();
private char[] buffer = new char[32];
+ private Charset charset;
+
+ public TPrintStream(TOutputStream out, boolean autoFlush, TString encoding) throws TUnsupportedEncodingException {
+ super(out);
+ this.autoFlush = autoFlush;
+ charset = Charset.get(encoding.toString());
+ if (charset == null) {
+ throw new TUnsupportedEncodingException(TString.wrap("Unsupported encoding: ").concat(encoding));
+ }
+ }
public TPrintStream(TOutputStream out, boolean autoFlush) {
super(out);
this.autoFlush = autoFlush;
+ this.charset = Charset.get("UTF-8");
}
public TPrintStream(TOutputStream out) {
@@ -100,7 +115,14 @@ public class TPrintStream extends TFilterOutputStream {
}
private void print(char[] s, int begin, int end) {
- int[] codePoints = new int[TMath.min(s.length, 4096)];
+ CharBuffer src = new CharBuffer(s, begin, end);
+ byte[] destBytes = new byte[TMath.max(16, TMath.min(s.length, 1024))];
+ ByteBuffer dest = new ByteBuffer(new byte[TMath.max(16, TMath.min(s.length, 1024))]);
+ while (!src.end()) {
+ charset.encode(src, dest);
+ write(destBytes, 0, dest.position());
+ dest.rewind(0);
+ }
}
public void print(char c) {
@@ -113,6 +135,20 @@ public class TPrintStream extends TFilterOutputStream {
printSB();
}
+ public void print(TString s) {
+ sb.append(s).append('\n');
+ printSB();
+ }
+
+ public void println(TString s) {
+ sb.append(s);
+ printSB();
+ }
+
+ public void println() {
+ print('\n');
+ }
+
private void printSB() {
char[] buffer = sb.length() > this.buffer.length ? new char[sb.length()] : this.buffer;
sb.getChars(0, sb.length(), buffer, 0);
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TSerializable.java
similarity index 64%
rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java
rename to teavm-classlib/src/main/java/org/teavm/classlib/java/io/TSerializable.java
index 33a11b51e..c7b0cc85b 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TSerializable.java
@@ -1,4 +1,4 @@
-package org.teavm.classlib.java.lang.io;
+package org.teavm.classlib.java.io;
/**
*
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUnsupportedEncodingException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUnsupportedEncodingException.java
new file mode 100644
index 000000000..9ceb8af52
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUnsupportedEncodingException.java
@@ -0,0 +1,19 @@
+package org.teavm.classlib.java.io;
+
+import org.teavm.classlib.java.lang.TString;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class TUnsupportedEncodingException extends TIOException {
+ private static final long serialVersionUID = 2403781130729330252L;
+
+ public TUnsupportedEncodingException() {
+ super();
+ }
+
+ public TUnsupportedEncodingException(TString message) {
+ super(message);
+ }
+}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ConsoleOutputStreamGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ConsoleOutputStreamGenerator.java
new file mode 100644
index 000000000..7e6a711b1
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ConsoleOutputStreamGenerator.java
@@ -0,0 +1,26 @@
+package org.teavm.classlib.java.lang;
+
+import java.io.IOException;
+import org.teavm.codegen.SourceWriter;
+import org.teavm.javascript.ni.Generator;
+import org.teavm.javascript.ni.GeneratorContext;
+import org.teavm.model.MethodReference;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class ConsoleOutputStreamGenerator implements Generator {
+ @Override
+ public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
+ if (methodRef.getClassName().endsWith("_stderr")) {
+ if (methodRef.getName().equals("write")) {
+ writer.append("$rt_putStderr(").append(context.getParameterName(1)).append(");").softNewLine();
+ }
+ } else if (methodRef.getClassName().endsWith("_stdout")) {
+ if (methodRef.getName().equals("write")) {
+ writer.append("$rt_putStdout(").append(context.getParameterName(1)).append(");").softNewLine();
+ }
+ }
+ }
+}
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 775937ecb..161dd5b9b 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
@@ -1,7 +1,7 @@
package org.teavm.classlib.java.lang;
import org.teavm.classlib.impl.charset.UTF16Helper;
-import org.teavm.classlib.java.lang.io.TSerializable;
+import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.util.TArrays;
import org.teavm.javascript.ni.Remove;
import org.teavm.javascript.ni.Rename;
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stderr.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stderr.java
new file mode 100644
index 000000000..e24f4166b
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stderr.java
@@ -0,0 +1,15 @@
+package org.teavm.classlib.java.lang;
+
+import org.teavm.classlib.java.io.TIOException;
+import org.teavm.classlib.java.io.TOutputStream;
+import org.teavm.javascript.ni.GeneratedBy;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class TConsoleOutputStream_stderr extends TOutputStream {
+ @Override
+ @GeneratedBy(ConsoleOutputStreamGenerator.class)
+ public native void write(int b) throws TIOException;
+}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stdout.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stdout.java
new file mode 100644
index 000000000..9b70299e7
--- /dev/null
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TConsoleOutputStream_stdout.java
@@ -0,0 +1,15 @@
+package org.teavm.classlib.java.lang;
+
+import org.teavm.classlib.java.io.TIOException;
+import org.teavm.classlib.java.io.TOutputStream;
+import org.teavm.javascript.ni.GeneratedBy;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+class TConsoleOutputStream_stdout extends TOutputStream {
+ @Override
+ @GeneratedBy(ConsoleOutputStreamGenerator.class)
+ public native void write(int b) throws TIOException;
+}
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 fb35e560d..bb927f552 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
@@ -1,7 +1,7 @@
package org.teavm.classlib.java.lang;
import org.teavm.classlib.impl.charset.UTF16Helper;
-import org.teavm.classlib.java.lang.io.TSerializable;
+import org.teavm.classlib.java.io.TSerializable;
import org.teavm.javascript.ni.GeneratedBy;
import org.teavm.javascript.ni.Rename;
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 1aff72f4d..94b65e65c 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
@@ -1,5 +1,6 @@
package org.teavm.classlib.java.lang;
+import org.teavm.classlib.java.io.TPrintStream;
import org.teavm.classlib.java.lang.reflect.TArray;
import org.teavm.javascript.ni.GeneratedBy;
@@ -8,6 +9,9 @@ import org.teavm.javascript.ni.GeneratedBy;
* @author Alexey Andreev
*/
public final class TSystem extends TObject {
+ public static final TPrintStream out = new TPrintStream(new TConsoleOutputStream_stdout(), false);
+ public static final TPrintStream err = new TPrintStream(new TConsoleOutputStream_stderr(), false);
+
private TSystem() {
}
diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java
index 1704e0e99..3bd5698d1 100644
--- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java
+++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java
@@ -68,7 +68,7 @@ public class TThrowable extends RuntimeException {
@Rename("getLocalizedMessage")
public TString getLocalizedMessage0() {
- return getMessage0();
+ return TString.wrap(getMessage());
}
@Override
diff --git a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java
index e766d971f..e388f9174 100644
--- a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java
+++ b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java
@@ -111,7 +111,7 @@ public class JavascriptBuilder {
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Platform does not support UTF-8", e);
} catch (IOException e) {
- throw new RenderingException();
+ throw new RenderingException("IO error occured", e);
}
}
}
diff --git a/teavm-core/src/main/java/org/teavm/model/resource/ClasspathResourceMapper.java b/teavm-core/src/main/java/org/teavm/model/resource/ClasspathResourceMapper.java
index 5a4f726cb..e3a5d29f8 100644
--- a/teavm-core/src/main/java/org/teavm/model/resource/ClasspathResourceMapper.java
+++ b/teavm-core/src/main/java/org/teavm/model/resource/ClasspathResourceMapper.java
@@ -79,7 +79,7 @@ public class ClasspathResourceMapper implements Mapper {
int index = name.lastIndexOf('.');
String className = name.substring(index + 1);
String packageName = name.substring(0, index);
- ClassHolder classHolder = innerMapper.map(transformation.packagePrefix + "." + packageName +
+ ClassHolder classHolder = innerMapper.map(transformation.packagePrefix + packageName +
"." + transformation.classPrefix + className);
if (classHolder != null) {
classHolder = renamer.rename(classHolder);
diff --git a/teavm-core/src/main/java/org/teavm/parsing/Parser.java b/teavm-core/src/main/java/org/teavm/parsing/Parser.java
index e51426f0d..432b13499 100644
--- a/teavm-core/src/main/java/org/teavm/parsing/Parser.java
+++ b/teavm-core/src/main/java/org/teavm/parsing/Parser.java
@@ -18,7 +18,7 @@ public class Parser {
MethodHolder method = new MethodHolder(node.name, signature);
parseModifiers(node.access, method);
ProgramParser programParser = new ProgramParser();
- Program program = programParser.parser(node);
+ Program program = programParser.parse(node);
new UnreachableBasicBlockEliminator().optimize(program);
SSATransformer ssaProducer = new SSATransformer();
ssaProducer.transformToSSA(program, method.getParameterTypes());
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 47c811b30..145dfd3ad 100644
--- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java
+++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java
@@ -53,7 +53,7 @@ public class ProgramParser {
}
}
- public Program parser(MethodNode method) {
+ public Program parse(MethodNode method) {
program = new Program();
InsnList instructions = method.instructions;
if (instructions.size() == 0) {
@@ -61,7 +61,11 @@ public class ProgramParser {
}
prepare(method);
prepareParameters(method);
+ program.createBasicBlock();
getBasicBlock(0);
+ JumpInstruction insn = new JumpInstruction();
+ insn.setTarget(program.basicBlockAt(1));
+ program.basicBlockAt(0).getInstructions().add(insn);
doAnalyze(method);
assemble();
return program;
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 76a6f872b..e926a7980 100644
--- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js
+++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js
@@ -248,6 +248,28 @@ $rt_methodStubs = function(clinit, names) {
})(names[i]);
}
}
+$rt_stdoutBuffer = "";
+$rt_putStdout = function(ch) {
+ if (ch == '\n') {
+ if (console) {
+ console.info($rt_stdoutBuffer);
+ }
+ $rt_stdoutBuffer = "";
+ } else {
+ $rt_stdoutBuffer += String.fromCharCode(ch);
+ }
+}
+$rt_stderrBuffer = "";
+$rt_putStderr = function(ch) {
+ if (ch == '\n') {
+ if (console) {
+ console.info($rt_stderrBuffer);
+ }
+ $rt_stderrBuffer = "";
+ } else {
+ $rt_stderrBuffer += String.fromCharCode(ch);
+ }
+}
Long = function(lo, hi) {
this.lo = lo | 0;
diff --git a/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java b/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java
index 85e5ae69b..a6e9e979e 100644
--- a/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java
+++ b/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java
@@ -12,6 +12,7 @@ import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.teavm.javascript.JavascriptBuilder;
import org.teavm.model.MethodDescriptor;
@@ -22,7 +23,8 @@ import org.teavm.model.ValueType;
*
* @author Alexey Andreev
*/
-@Mojo(name = "build-javascript")
+@Mojo(name = "build-javascript", requiresDependencyResolution = ResolutionScope.COMPILE,
+ requiresDependencyCollection = ResolutionScope.COMPILE)
public class BuildJavascriptMojo extends AbstractMojo {
private static Set compileScopes = new HashSet<>(Arrays.asList(
Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM));
@@ -70,6 +72,7 @@ public class BuildJavascriptMojo extends AbstractMojo {
ValueType.object("java.lang.String")), ValueType.VOID);
builder.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
.withValue(1, "java.lang.String");
+ targetFile.getParentFile().mkdirs();
builder.build(targetFile);
log.info("JavaScript file successfully built");
} catch (RuntimeException e) {
@@ -94,9 +97,13 @@ public class BuildJavascriptMojo extends AbstractMojo {
classpath.append(file.getPath());
urls.add(file.toURI().toURL());
}
- log.info("Using the following classpath for JavaScript generation: " + classpath);
+ if (classpath.length() > 0) {
+ classpath.append(':');
+ }
+ classpath.append(classFiles.getPath());
urls.add(classFiles.toURI().toURL());
- return new URLClassLoader(urls.toArray(new URL[urls.size()]));
+ log.info("Using the following classpath for JavaScript generation: " + classpath);
+ return new URLClassLoader(urls.toArray(new URL[urls.size()]), BuildJavascriptMojo.class.getClassLoader());
} catch (MalformedURLException e) {
throw new MojoExecutionException("Error gathering classpath information", e);
}
diff --git a/teavm-samples/.gitignore b/teavm-samples/.gitignore
new file mode 100644
index 000000000..c708c363d
--- /dev/null
+++ b/teavm-samples/.gitignore
@@ -0,0 +1,4 @@
+/target
+/.settings
+/.classpath
+/.project
diff --git a/teavm-samples/pom.xml b/teavm-samples/pom.xml
new file mode 100644
index 000000000..ffedbd11e
--- /dev/null
+++ b/teavm-samples/pom.xml
@@ -0,0 +1,79 @@
+
+ 4.0.0
+
+ org.teavm
+ teavm
+ 0.0.1-SNAPSHOT
+
+ teavm-samples
+
+
+
+ org.teavm
+ teavm-classlib
+ 0.0.1-SNAPSHOT
+ provided
+
+
+
+
+
+
+ org.teavm
+ teavm-maven-plugin
+ ${project.version}
+
+
+ org.teavm
+ teavm-core
+ ${project.version}
+
+
+
+
+ generate-javascript
+
+ build-javascript
+
+ process-classes
+
+ false
+ org.teavm.samples.HelloWorld
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.teavm
+ teavm-maven-plugin
+ [0.0.1-SNAPSHOT,)
+
+ build-javascript
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java
new file mode 100644
index 000000000..e8789289b
--- /dev/null
+++ b/teavm-samples/src/main/java/org/teavm/samples/HelloWorld.java
@@ -0,0 +1,11 @@
+package org.teavm.samples;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class HelloWorld {
+ public static void main(String[] args) {
+ System.out.println("Hello, world!");
+ }
+}