From dd25ae4759716d735fe6f93a54c8bfab2e7fc7bf Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 9 Feb 2015 19:36:45 +0400 Subject: [PATCH] Further removal of direct JavaScript generation from classlib --- .../org/teavm/classlib/impl/JCLPlugin.java | 2 - .../java/lang/CharacterMetadataGenerator.java | 54 +++++++++ .../java/lang/CharacterNativeGenerator.java | 88 -------------- .../java/lang/ClassNativeGenerator.java | 37 ------ .../lang/ConsoleOutputStreamGenerator.java | 41 ------- .../java/lang/ObjectNativeGenerator.java | 110 ------------------ .../java/lang/StringNativeGenerator.java | 49 -------- .../java/lang/SystemNativeGenerator.java | 3 - .../teavm/classlib/java/lang/TBoolean.java | 2 - .../teavm/classlib/java/lang/TCharacter.java | 40 ++++--- .../org/teavm/classlib/java/lang/TClass.java | 6 +- .../lang/TConsoleOutputStream_stderr.java | 7 +- .../lang/TConsoleOutputStream_stdout.java | 7 +- .../org/teavm/classlib/java/lang/TObject.java | 42 ++++--- .../org/teavm/classlib/java/lang/TString.java | 8 +- .../org/teavm/classlib/java/lang/TSystem.java | 6 +- .../java/lang/ThreadNativeGenerator.java | 49 -------- .../java/org/teavm/platform/Platform.java | 20 ++++ .../org/teavm/platform/PlatformConsole.java | 31 +++++ .../org/teavm/platform/PlatformHelper.java | 32 +++++ .../org/teavm/platform/PlatformObject.java | 6 + .../org/teavm/platform/PlatformString.java | 30 +++++ .../teavm/platform/PlatformStringClass.java | 26 +++++ .../plugin}/EnumDependencySupport.java | 7 +- .../platform/plugin}/EnumTransformer.java | 2 +- .../platform/plugin/PlatformGenerator.java | 22 ++++ .../teavm/platform/plugin/PlatformPlugin.java | 2 + 27 files changed, 288 insertions(+), 441 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterMetadataGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterNativeGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ConsoleOutputStreamGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ObjectNativeGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringNativeGenerator.java delete mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ThreadNativeGenerator.java create mode 100644 teavm-platform/src/main/java/org/teavm/platform/PlatformConsole.java create mode 100644 teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java create mode 100644 teavm-platform/src/main/java/org/teavm/platform/PlatformString.java create mode 100644 teavm-platform/src/main/java/org/teavm/platform/PlatformStringClass.java rename {teavm-classlib/src/main/java/org/teavm/classlib/impl => teavm-platform/src/main/java/org/teavm/platform/plugin}/EnumDependencySupport.java (93%) rename {teavm-classlib/src/main/java/org/teavm/classlib/impl => teavm-platform/src/main/java/org/teavm/platform/plugin}/EnumTransformer.java (97%) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java index 7a86e690f..895bf3d49 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java @@ -29,8 +29,6 @@ import org.teavm.vm.spi.TeaVMPlugin; public class JCLPlugin implements TeaVMPlugin { @Override public void install(TeaVMHost host) { - host.add(new EnumDependencySupport()); - host.add(new EnumTransformer()); host.add(new ObjectEnrichRenderer()); ServiceLoaderSupport serviceLoaderSupp = new ServiceLoaderSupport(host.getClassLoader()); host.add(serviceLoaderSupp); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterMetadataGenerator.java new file mode 100644 index 000000000..ea21a6a5a --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterMetadataGenerator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 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.impl.unicode.UnicodeHelper; +import org.teavm.classlib.impl.unicode.UnicodeSupport; +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.MetadataGenerator; +import org.teavm.platform.metadata.MetadataGeneratorContext; +import org.teavm.platform.metadata.Resource; +import org.teavm.platform.metadata.StringResource; + +/** + * + * @author Alexey Andreev + */ +public class CharacterMetadataGenerator implements MetadataGenerator { + @Override + public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { + switch (method.getName()) { + case "obtainDigitMapping": + return generateObtainDigitMapping(context); + case "obtainClasses": + return generateObtainClasses(context); + default: + return null; + } + } + + private Resource generateObtainDigitMapping(MetadataGeneratorContext context) { + StringResource res = context.createResource(StringResource.class); + res.setValue(UnicodeHelper.encodeIntByte(UnicodeSupport.getDigitValues())); + return res; + } + + private Resource generateObtainClasses(MetadataGeneratorContext context) { + StringResource res = context.createResource(StringResource.class); + res.setValue(UnicodeHelper.compressRle(UnicodeSupport.getClasses())); + return res; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterNativeGenerator.java deleted file mode 100644 index ebae587c6..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/CharacterNativeGenerator.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 java.io.IOException; -import org.teavm.classlib.impl.unicode.UnicodeHelper; -import org.teavm.classlib.impl.unicode.UnicodeSupport; -import org.teavm.codegen.SourceWriter; -import org.teavm.dependency.DependencyAgent; -import org.teavm.dependency.DependencyPlugin; -import org.teavm.dependency.MethodDependency; -import org.teavm.javascript.spi.Generator; -import org.teavm.javascript.spi.GeneratorContext; -import org.teavm.model.CallLocation; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class CharacterNativeGenerator implements Generator, DependencyPlugin { - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "toLowerCase": - writer.append("return String.fromCharCode(").append(context.getParameterName(1)) - .append(").toLowerCase().charCodeAt(0)|0;").softNewLine(); - break; - case "toUpperCase": - writer.append("return String.fromCharCode(").append(context.getParameterName(1)) - .append(").toUpperCase().charCodeAt(0)|0;").softNewLine(); - break; - case "obtainDigitMapping": - generateObtainDigitMapping(writer); - break; - case "obtainClasses": - generateObtainClasses(writer); - break; - } - } - - @Override - public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) { - switch (method.getReference().getName()) { - case "obtainDigitMapping": - case "obtainClasses": - method.getResult().propagate(agent.getType("java.lang.String")); - break; - } - } - - private void generateObtainDigitMapping(SourceWriter writer) throws IOException { - String str = UnicodeHelper.encodeIntByte(UnicodeSupport.getDigitValues()); - writer.append("return $rt_str("); - splitString(writer, str); - writer.append(");").softNewLine(); - } - - private void generateObtainClasses(SourceWriter writer) throws IOException { - String str = UnicodeHelper.compressRle(UnicodeSupport.getClasses()); - writer.append("return $rt_str("); - splitString(writer, str); - writer.append(");").softNewLine(); - } - - private void splitString(SourceWriter writer, String str) throws IOException { - for (int i = 0; i < str.length(); i += 512) { - if (i > 0) { - writer.ws().append("+").newLine(); - } - int j = Math.min(i + 512, str.length()); - writer.append("\"").append(str.substring(i, j)).append("\""); - } - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java deleted file mode 100644 index ccf99dee3..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2013 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 java.io.IOException; -import org.teavm.javascript.spi.Injector; -import org.teavm.javascript.spi.InjectorContext; -import org.teavm.model.*; - -/** - * - * @author Alexey Andreev - */ -public class ClassNativeGenerator implements Injector { - @Override - public void generate(InjectorContext context, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "getEnumConstantsImpl": - context.writeExpr(context.getArgument(0)); - context.getWriter().append(".values()"); - break; - } - } -} 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 deleted file mode 100644 index 713140245..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ConsoleOutputStreamGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013 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 java.io.IOException; -import org.teavm.codegen.SourceWriter; -import org.teavm.javascript.spi.Generator; -import org.teavm.javascript.spi.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/ObjectNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ObjectNativeGenerator.java deleted file mode 100644 index e95abdc3b..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ObjectNativeGenerator.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2013 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 java.io.IOException; -import org.teavm.codegen.SourceWriter; -import org.teavm.dependency.*; -import org.teavm.javascript.spi.Generator; -import org.teavm.javascript.spi.GeneratorContext; -import org.teavm.javascript.spi.Injector; -import org.teavm.javascript.spi.InjectorContext; -import org.teavm.model.CallLocation; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class ObjectNativeGenerator implements Generator, Injector, DependencyPlugin { - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - switch (methodRef.getDescriptor().getName()) { - case "": - generateInit(context, writer); - break; - case "hashCode": - case "identity": - generateHashCode(context, writer); - break; - case "clone": - generateClone(context, writer); - break; - } - } - - @Override - public void generate(InjectorContext context, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "getClass": - generateGetClass(context); - break; - case "wrap": - generateWrap(context); - break; - } - } - - @Override - public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) { - switch (method.getReference().getName()) { - case "clone": - method.getVariable(0).connect(method.getResult()); - break; - case "getClass": - achieveGetClass(agent, method); - break; - case "wrap": - method.getVariable(1).connect(method.getResult()); - break; - } - } - - private void generateInit(GeneratorContext context, SourceWriter writer) throws IOException { - writer.append(context.getParameterName(0)).append(".$id = $rt_nextId();").softNewLine(); - } - - private void generateGetClass(InjectorContext context) throws IOException { - SourceWriter writer = context.getWriter(); - writer.append("$rt_cls("); - context.writeExpr(context.getArgument(0)); - writer.append(".constructor)"); - } - - private void achieveGetClass(DependencyAgent agent, MethodDependency method) { - MethodReference initMethod = new MethodReference(Class.class, "createNew", Class.class); - agent.linkMethod(initMethod, null).use(); - method.getResult().propagate(agent.getType("java.lang.Class")); - } - - private void generateHashCode(GeneratorContext context, SourceWriter writer) throws IOException { - writer.append("return ").append(context.getParameterName(0)).append(".$id;").softNewLine(); - } - - private void generateClone(GeneratorContext context, SourceWriter writer) throws IOException { - String obj = context.getParameterName(0); - writer.append("var copy = new ").append(obj).append(".constructor();").softNewLine(); - writer.append("for (var field in " + obj + ") {").softNewLine().indent(); - writer.append("if (!" + obj + ".hasOwnProperty(field)) {").softNewLine().indent(); - writer.append("continue;").softNewLine().outdent().append("}").softNewLine(); - writer.append("copy[field] = " + obj + "[field];").softNewLine().outdent().append("}").softNewLine(); - writer.append("return copy;").softNewLine(); - } - - private void generateWrap(InjectorContext context) throws IOException { - context.writeExpr(context.getArgument(0)); - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringNativeGenerator.java deleted file mode 100644 index 79c131f5c..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringNativeGenerator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013 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 java.io.IOException; -import org.teavm.dependency.DependencyAgent; -import org.teavm.dependency.DependencyPlugin; -import org.teavm.dependency.MethodDependency; -import org.teavm.javascript.spi.Injector; -import org.teavm.javascript.spi.InjectorContext; -import org.teavm.model.CallLocation; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class StringNativeGenerator implements Injector, DependencyPlugin { - @Override - public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) { - switch (method.getReference().getName()) { - case "wrap": - method.getVariable(1).connect(method.getResult()); - break; - } - } - - @Override - public void generate(InjectorContext context, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "wrap": - context.writeExpr(context.getArgument(0)); - break; - } - } -} 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 5092802ba..65bb9ba6e 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 @@ -48,9 +48,6 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin { .appendField(new FieldReference("java.lang.System", "err")) .ws().append('=').ws().append(context.getParameterName(1)).append(";").softNewLine(); break; - case "identityHashCode": - writer.append("return ").append(context.getParameterName(1)).append(".$id;").softNewLine(); - break; } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TBoolean.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TBoolean.java index e898feac8..14c3772c9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TBoolean.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TBoolean.java @@ -16,7 +16,6 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.java.io.TSerializable; -import org.teavm.javascript.spi.GeneratedBy; /** * @@ -80,7 +79,6 @@ public class TBoolean extends TObject implements TSerializable, TComparable { return UTF16Helper.lowSurrogate(codePoint); } - // TODO: implement toLowerCase/toUpperCase/toTitleCase using UnicodeData.txt instead of built-in JS - @GeneratedBy(CharacterNativeGenerator.class) - public static native char toLowerCase(char ch); + public static char toLowerCase(char ch) { + return (char)toLowerCase((int)ch); + } - @GeneratedBy(CharacterNativeGenerator.class) - public static native int toLowerCase(int ch); + public static int toLowerCase(int ch) { + return Platform.stringFromCharCode(ch).toLowerCase().charCodeAt(0); + } - @GeneratedBy(CharacterNativeGenerator.class) - public static native char toUpperCase(char ch); + public static char toUpperCase(char ch) { + return (char)toUpperCase((int)ch); + } - @GeneratedBy(CharacterNativeGenerator.class) - public static native int toUpperCase(int codePoint); + public static int toUpperCase(int codePoint) { + return Platform.stringFromCharCode(codePoint).toUpperCase().charCodeAt(0); + } public static int digit(char ch, int radix) { return digit((int)ch, radix); @@ -286,25 +290,23 @@ public class TCharacter extends TObject implements TComparable { private static int[] getDigitMapping() { if (digitMapping == null) { - digitMapping = UnicodeHelper.decodeIntByte(obtainDigitMapping()); + digitMapping = UnicodeHelper.decodeIntByte(obtainDigitMapping().getValue()); } return digitMapping; } - @GeneratedBy(CharacterNativeGenerator.class) - @PluggableDependency(CharacterNativeGenerator.class) - private static native String obtainDigitMapping(); + @MetadataProvider(CharacterMetadataGenerator.class) + private static native StringResource obtainDigitMapping(); private static UnicodeHelper.Range[] getClasses() { if (classMapping == null) { - classMapping = UnicodeHelper.extractRle(obtainClasses()); + classMapping = UnicodeHelper.extractRle(obtainClasses().getValue()); } return classMapping; } - @GeneratedBy(CharacterNativeGenerator.class) - @PluggableDependency(CharacterNativeGenerator.class) - private static native String obtainClasses(); + @MetadataProvider(CharacterMetadataGenerator.class) + private static native StringResource obtainClasses(); public static int toChars(int codePoint, char[] dst, int dstIndex) { if (codePoint >= UTF16Helper.SUPPLEMENTARY_PLANE) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 814e01b82..642a28069 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -16,7 +16,6 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.impl.DeclaringClassMetadataGenerator; -import org.teavm.javascript.spi.InjectedBy; import org.teavm.platform.Platform; import org.teavm.platform.PlatformClass; import org.teavm.platform.metadata.ClassResource; @@ -144,12 +143,9 @@ public class TClass extends TObject { @SuppressWarnings("unchecked") public T[] getEnumConstants() { - return isEnum() ? (T[])getEnumConstantsImpl(platformClass) : null; + return isEnum() ? (T[])Platform.getEnumConstants(platformClass) : null; } - @InjectedBy(ClassNativeGenerator.class) - private static native Object[] getEnumConstantsImpl(PlatformClass cls); - @SuppressWarnings("unchecked") public T cast(TObject obj) { if (obj != null && !isAssignableFrom((TClass)(Object)obj.getClass())) { 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 index b102af538..09038fd60 100644 --- 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 @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.java.io.TIOException; import org.teavm.classlib.java.io.TOutputStream; -import org.teavm.javascript.spi.GeneratedBy; +import org.teavm.platform.Platform; /** * @@ -25,6 +25,7 @@ import org.teavm.javascript.spi.GeneratedBy; */ class TConsoleOutputStream_stderr extends TOutputStream { @Override - @GeneratedBy(ConsoleOutputStreamGenerator.class) - public native void write(int b) throws TIOException; + public void write(int b) throws TIOException { + Platform.getConsole().error(b); + } } 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 index 9abdcb7b4..4c816bfb4 100644 --- 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 @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.java.io.TIOException; import org.teavm.classlib.java.io.TOutputStream; -import org.teavm.javascript.spi.GeneratedBy; +import org.teavm.platform.Platform; /** * @@ -25,6 +25,7 @@ import org.teavm.javascript.spi.GeneratedBy; */ class TConsoleOutputStream_stdout extends TOutputStream { @Override - @GeneratedBy(ConsoleOutputStreamGenerator.class) - public native void write(int b) throws TIOException; + public void write(int b) throws TIOException { + Platform.getConsole().output(b); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index d3e51b64b..b248f7fe5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -15,11 +15,9 @@ */ package org.teavm.classlib.java.lang; -import org.teavm.dependency.PluggableDependency; -import org.teavm.javascript.spi.GeneratedBy; -import org.teavm.javascript.spi.InjectedBy; import org.teavm.javascript.spi.Rename; import org.teavm.javascript.spi.Superclass; +import org.teavm.platform.Platform; /** * @@ -31,18 +29,20 @@ public class TObject { public TObject() { } - @GeneratedBy(ObjectNativeGenerator.class) @Rename("") - private native void init(); + private void init() { + Platform.getPlatformObject(this).setId(Platform.nextObjectId()); + } - @InjectedBy(ObjectNativeGenerator.class) @Rename("getClass") - @PluggableDependency(ObjectNativeGenerator.class) - public native final TClass getClass0(); + public final TClass getClass0() { + return TClass.getClass(Platform.getPlatformObject(this).getPlatformClass()); + } @Override - @GeneratedBy(ObjectNativeGenerator.class) - public native int hashCode(); + public int hashCode() { + return identity(); + } @Rename("equals") public boolean equals0(TObject other) { @@ -54,13 +54,19 @@ public class TObject { return getClass().getName() + "@" + TInteger.toHexString(identity()); } - @GeneratedBy(ObjectNativeGenerator.class) - native int identity(); + int identity() { + return Platform.getPlatformObject(this).getId(); + } - @GeneratedBy(ObjectNativeGenerator.class) - @PluggableDependency(ObjectNativeGenerator.class) @Override - protected native Object clone() throws TCloneNotSupportedException; + protected Object clone() throws TCloneNotSupportedException { + if (!(this instanceof TCloneable) && Platform.getPlatformObject(this) + .getPlatformClass().getMetadata().getArrayItem() == null) { + throw new TCloneNotSupportedException(); + } + Platform.getPlatformObject(this).setId(Platform.nextObjectId()); + return Platform.clone(this); + } @Rename("notify") public final void notify0() { @@ -88,7 +94,7 @@ public class TObject { protected void finalize() throws TThrowable { } - @InjectedBy(ObjectNativeGenerator.class) - @PluggableDependency(ObjectNativeGenerator.class) - public static native TObject wrap(Object obj); + public static TObject wrap(Object obj) { + return (TObject)obj; + } } 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 a5bbde544..a5ba75b2c 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 @@ -23,8 +23,6 @@ import org.teavm.classlib.java.util.TComparator; import org.teavm.classlib.java.util.THashMap; import org.teavm.classlib.java.util.TMap; import org.teavm.classlib.java.util.regex.TPattern; -import org.teavm.dependency.PluggableDependency; -import org.teavm.javascript.spi.InjectedBy; /** * @@ -592,9 +590,9 @@ public class TString extends TObject implements TSerializable, TComparable - */ -public class ThreadNativeGenerator implements Generator { - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - if (methodRef.getName().equals("sleep")) { - generateSleep(context, writer); - } else if (methodRef.getName().equals("yield")) { - generateYield(context, writer); - } - } - - private void generateSleep(GeneratorContext context, SourceWriter writer) throws IOException { - writer.append("setTimeout(function() {").indent().softNewLine(); - writer.append(context.getCompleteContinuation()).append("($rt_asyncResult(null));").softNewLine(); - writer.outdent().append("},").ws().append(context.getParameterName(1)).append(");").softNewLine(); - } - - private void generateYield(GeneratorContext context, SourceWriter writer) throws IOException { - writer.append("setTimeout(function() {").indent().softNewLine(); - writer.append(context.getCompleteContinuation()).append("($rt_asyncResult(null));").softNewLine(); - writer.outdent().append("},").ws().append("0);").softNewLine(); - } -} diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index acbcd595e..38c43fcfd 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -34,6 +34,10 @@ public final class Platform { return (PlatformObject)JS.marshall(obj); } + @GeneratedBy(PlatformGenerator.class) + @PluggableDependency(PlatformGenerator.class) + public static native Object clone(Object obj); + public static boolean isInstance(PlatformObject obj, PlatformClass cls) { return obj != null && !JS.isUndefined(obj.getPlatformClass().getMetadata()) && isAssignable(obj.getPlatformClass(), cls); @@ -60,6 +64,14 @@ public final class Platform { return (PlatformPrimitives)JS.getGlobal(); } + public static PlatformConsole getConsole() { + return (PlatformConsole)JS.getGlobal(); + } + + public static int nextObjectId() { + return ((PlatformHelper)JS.getGlobal()).nextId(); + } + @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) public static native T newInstance(PlatformClass cls); @@ -75,4 +87,12 @@ public final class Platform { @InjectedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) public static native PlatformClass classFromResource(ClassResource resource); + + @InjectedBy(PlatformGenerator.class) + @PluggableDependency(PlatformGenerator.class) + public static native Enum[] getEnumConstants(PlatformClass cls); + + public static PlatformString stringFromCharCode(int charCode) { + return ((PlatformHelper)JS.getGlobal()).getStringClass().fromCharCode(charCode); + } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformConsole.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformConsole.java new file mode 100644 index 000000000..2db3a7a7f --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformConsole.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 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.platform; + +import org.teavm.jso.JSMethod; +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface PlatformConsole extends JSObject { + @JSMethod("rt_putStdout") + void output(int b); + + @JSMethod("rt_putStderr") + void error(int b); +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java new file mode 100644 index 000000000..48f851b2c --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 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.platform; + +import org.teavm.jso.JSMethod; +import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +interface PlatformHelper extends JSObject { + @JSMethod("$rt_nextId") + int nextId(); + + @JSProperty("String") + PlatformStringClass getStringClass(); +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java index 1e547f331..0c18bec4a 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java @@ -25,4 +25,10 @@ import org.teavm.jso.JSProperty; public interface PlatformObject extends JSObject { @JSProperty("constructor") PlatformClass getPlatformClass(); + + @JSProperty("$id") + int getId(); + + @JSProperty("$id") + void setId(int id); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformString.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformString.java new file mode 100644 index 000000000..6b83bda7f --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformString.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 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.platform; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface PlatformString extends JSObject { + PlatformString toUpperCase(); + + PlatformString toLowerCase(); + + int charCodeAt(int index); +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformStringClass.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformStringClass.java new file mode 100644 index 000000000..45633f34e --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformStringClass.java @@ -0,0 +1,26 @@ +/* + * Copyright 2015 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.platform; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +interface PlatformStringClass extends JSObject { + PlatformString fromCharCode(int charCode); +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java similarity index 93% rename from teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumDependencySupport.java rename to teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java index 190defd64..fe0deb778 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.classlib.impl; +package org.teavm.platform.plugin; import org.teavm.dependency.*; import org.teavm.model.CallLocation; @@ -21,6 +21,7 @@ import org.teavm.model.ClassReader; import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReader; import org.teavm.model.ValueType; +import org.teavm.platform.Platform; /** * @@ -53,8 +54,8 @@ public class EnumDependencySupport implements DependencyListener { @Override public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) { - if (method.getReference().getClassName().equals("java.lang.Class") && - method.getReference().getName().equals("getEnumConstantsImpl")) { + if (method.getReference().getClassName().equals(Platform.class.getName()) && + method.getReference().getName().equals("getEnumConstants")) { unlocked = true; allEnums.connect(method.getResult().getArrayItem()); method.getResult().propagate(agent.getType("[java.lang.Enum")); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumTransformer.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumTransformer.java similarity index 97% rename from teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumTransformer.java rename to teavm-platform/src/main/java/org/teavm/platform/plugin/EnumTransformer.java index dd4b7e213..4be7e36a0 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/EnumTransformer.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumTransformer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.classlib.impl; +package org.teavm.platform.plugin; import org.teavm.diagnostics.Diagnostics; import org.teavm.javascript.spi.PreserveOriginalName; diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index 29514da6f..5d812c02f 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -37,6 +37,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin case "asJavaClass": method.getResult().propagate(agent.getType("java.lang.Class")); return; + case "clone": + method.getVariable(0).connect(method.getResult()); + break; } } @@ -47,6 +50,10 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin case "classFromResource": context.writeExpr(context.getArgument(0)); return; + case "getEnumConstants": + context.writeExpr(context.getArgument(0)); + context.getWriter().append(".values()"); + break; } } @@ -59,6 +66,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin case "lookupClass": generateLookup(context, writer); break; + case "clone": + generateClone(context, writer); + break; } } @@ -95,4 +105,16 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin writer.append("default: return null;").softNewLine(); writer.outdent().append("}").softNewLine(); } + + private void generateClone(GeneratorContext context, SourceWriter writer) throws IOException { + String obj = context.getParameterName(1); + writer.append("var copy").ws().append("=").ws().append("new ").append(obj).append(".constructor();") + .softNewLine(); + writer.append("for").ws().append("(var field in " + obj + ")").ws().append("{").softNewLine().indent(); + writer.append("if").ws().append("(!" + obj + ".hasOwnProperty(field))").ws().append("{").softNewLine().indent(); + writer.append("continue;").softNewLine().outdent().append("}").softNewLine(); + writer.append("copy[field]").ws().append("=").ws().append(obj).append("[field];") + .softNewLine().outdent().append("}").softNewLine(); + writer.append("return copy;").softNewLine(); + } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java index 805709fac..710e0c718 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java @@ -32,5 +32,7 @@ public class PlatformPlugin implements TeaVMPlugin { host.add(new AsyncMethodProcessor()); host.add(new NewInstanceDependencySupport()); host.add(new ClassLookupDependencySupport()); + host.add(new EnumDependencySupport()); + host.add(new EnumTransformer()); } }