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!"); + } +}