From 712dfced8b3f803bb32a048f5c896ef8d49c6d44 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 30 Mar 2015 22:31:30 +0300 Subject: [PATCH 1/3] Make Arrays.hashCode compatible with JVM --- .../org/teavm/classlib/java/util/TArrays.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java index cd6ac97e6..0817a1dc4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java @@ -1358,9 +1358,9 @@ public class TArrays extends TObject { if (a == null) { return 0; } - int hash = 0xA5A537FC; + int hash = 1; for (int i = 0; i < a.length; ++i) { - hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); + hash = 31 * hash + a[i]; } return hash; } @@ -1369,9 +1369,9 @@ public class TArrays extends TObject { if (a == null) { return 0; } - int hash = 0xA5A537FC; + int hash = 1; for (int i = 0; i < a.length; ++i) { - hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); + hash = 31 * hash + a[i]; } return hash; } @@ -1380,9 +1380,9 @@ public class TArrays extends TObject { if (a == null) { return 0; } - int hash = 0xA5A537FC; + int hash = 1; for (int i = 0; i < a.length; ++i) { - hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); + hash = 31 * hash + a[i]; } return hash; } @@ -1391,9 +1391,9 @@ public class TArrays extends TObject { if (a == null) { return 0; } - int hash = 0xA5A537FC; + int hash = 1; for (int i = 0; i < a.length; ++i) { - hash = TInteger.rotateLeft(a[i], 4) ^ TInteger.rotateRight(a[i], 7) ^ TInteger.rotateLeft(hash, 13); + hash = 31 * hash + a[i]; } return hash; } From 4adf789142e6788b16f9641918872f819d92e634 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 1 Apr 2015 00:10:51 +0300 Subject: [PATCH 2/3] Fixing bugs in JSBody --- .../java/org/teavm/model/util/ModelUtils.java | 2 +- teavm-jso/src/main/java/org/teavm/jso/JS.java | 2 +- .../org/teavm/jso/plugin/JSBodyGenerator.java | 2 +- .../jso/plugin/JavascriptNativeProcessor.java | 40 +++++++++++++++---- .../NativeJavascriptClassRepository.java | 5 +++ 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java b/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java index f728d144b..9fb039bc7 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java +++ b/teavm-core/src/main/java/org/teavm/model/util/ModelUtils.java @@ -65,7 +65,7 @@ public final class ModelUtils { return copy; } - private static void copyAnnotations(AnnotationContainerReader src, AnnotationContainer dst) { + public static void copyAnnotations(AnnotationContainerReader src, AnnotationContainer dst) { for (AnnotationReader annot : src.all()) { dst.add(copyAnnotation(annot)); } diff --git a/teavm-jso/src/main/java/org/teavm/jso/JS.java b/teavm-jso/src/main/java/org/teavm/jso/JS.java index bd99b5f6f..a0dc42cde 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JS.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JS.java @@ -479,7 +479,7 @@ public final class JS { }; } - public static Iterable iterate(final JSStringArrayReader array) { + public static Iterable iterate(final JSStringArrayReader array) { return new Iterable() { @Override public Iterator iterator() { return new Iterator() { diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java index 40c3525a2..d7abe2da4 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java @@ -35,7 +35,7 @@ public class JSBodyGenerator implements Generator { boolean isStatic = annot.getValue("isStatic").getBoolean(); List paramNames = annot.getValue("params").getList(); - int bodyParamCount = method.parameterCount(); + int bodyParamCount = isStatic ? method.parameterCount() : method.parameterCount() - 1; int offset = isStatic ? 1 : 0; writer.append("if (!").appendMethodBody(methodRef).append(".$native)").ws().append('{').indent().newLine(); diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java index e55d0a2b9..76e04f012 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java @@ -23,6 +23,7 @@ import org.teavm.jso.*; import org.teavm.model.*; import org.teavm.model.instructions.*; import org.teavm.model.util.InstructionVariableMapper; +import org.teavm.model.util.ModelUtils; import org.teavm.model.util.ProgramUtils; /** @@ -80,7 +81,11 @@ class JavascriptNativeProcessor { public void processFinalMethods(ClassHolder cls) { // TODO: don't allow final methods to override anything for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { - if (method.hasModifier(ElementModifier.FINAL) && method.getProgram() != null) { + if (method.hasModifier(ElementModifier.STATIC)) { + continue; + } + if (method.hasModifier(ElementModifier.FINAL) && method.getProgram() != null && + method.getProgram().basicBlockCount() > 0) { ValueType[] staticSignature = getStaticSignature(method.getReference()); MethodHolder callerMethod = new MethodHolder(new MethodDescriptor(method.getName() + "$static", staticSignature)); @@ -115,6 +120,7 @@ class JavascriptNativeProcessor { } } callerMethod.setProgram(program); + ModelUtils.copyAnnotations(method.getAnnotations(), callerMethod.getAnnotations()); cls.addMethod(callerMethod); } } @@ -188,11 +194,13 @@ class JavascriptNativeProcessor { continue; } if (method.hasModifier(ElementModifier.FINAL)) { - invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static", - getStaticSignature(method.getReference()))); + if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) { + invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static", + getStaticSignature(method.getReference()))); + invoke.getArguments().add(0, invoke.getInstance()); + invoke.setInstance(null); + } invoke.setType(InvocationType.SPECIAL); - invoke.getArguments().add(0, invoke.getInstance()); - invoke.setInstance(null); continue; } CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation()); @@ -390,6 +398,9 @@ class JavascriptNativeProcessor { for (int i = 0; i < paramCount; ++i) { params.add(program.createVariable()); } + if (isStatic) { + program.createVariable(); + } methodToProcess.setProgram(program); // Generate invoke instruction @@ -398,7 +409,7 @@ class JavascriptNativeProcessor { invoke.setType(InvocationType.SPECIAL); invoke.setMethod(proxyMethod.getReference()); for (int i = 0; i < paramCount; ++i) { - Variable var = program.createVariable(); + Variable var = program.variableAt(isStatic ? i + 1 : i); invoke.getArguments().add(wrapArgument(location, var, paramTypes[i])); } block.getInstructions().addAll(replacement); @@ -580,7 +591,7 @@ class JavascriptNativeProcessor { } Variable result = program.createVariable(); InvokeInstruction insn = new InvokeInstruction(); - insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type, getWrapperType(type))); + insn.setMethod(new MethodReference(JS.class.getName(), "wrap", getWrappedType(type), getWrapperType(type))); insn.getArguments().add(var); insn.setReceiver(result); insn.setType(InvocationType.SPECIAL); @@ -589,6 +600,21 @@ class JavascriptNativeProcessor { return result; } + private ValueType getWrappedType(ValueType type) { + if (type instanceof ValueType.Array) { + ValueType itemType = ((ValueType.Array)type).getItemType(); + return ValueType.arrayOf(getWrappedType(itemType)); + } else if (type instanceof ValueType.Object) { + if (type.isObject("java.lang.String")) { + return type; + } else { + return ValueType.parse(JSObject.class); + } + } else { + return type; + } + } + private ValueType getWrapperType(ValueType type) { if (type instanceof ValueType.Array) { ValueType itemType = ((ValueType.Array)type).getItemType(); diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/NativeJavascriptClassRepository.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/NativeJavascriptClassRepository.java index 4b2483a1b..b7429789c 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/NativeJavascriptClassRepository.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/NativeJavascriptClassRepository.java @@ -64,6 +64,11 @@ class NativeJavascriptClassRepository { return true; } } + if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { + if (isJavaScriptClass(cls.getParent())) { + return true; + } + } return false; } From b8fa0a541a80db6310365bac264e8cc17bee977d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 1 Apr 2015 18:28:31 +0400 Subject: [PATCH 3/3] Fix bugs in JSBody --- teavm-jso/src/main/java/org/teavm/jso/JSFunctor.java | 6 ++---- .../main/java/org/teavm/jso/plugin/JSBodyGenerator.java | 9 ++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSFunctor.java b/teavm-jso/src/main/java/org/teavm/jso/JSFunctor.java index 8cd7c904c..4ac09aa88 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSFunctor.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSFunctor.java @@ -15,10 +15,7 @@ */ package org.teavm.jso; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * @@ -26,5 +23,6 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface JSFunctor { } diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java index d7abe2da4..0e496c4e7 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java @@ -36,16 +36,15 @@ public class JSBodyGenerator implements Generator { List paramNames = annot.getValue("params").getList(); int bodyParamCount = isStatic ? method.parameterCount() : method.parameterCount() - 1; - int offset = isStatic ? 1 : 0; writer.append("if (!").appendMethodBody(methodRef).append(".$native)").ws().append('{').indent().newLine(); writer.appendMethodBody(methodRef).append(".$native").ws().append('=').ws().append("function("); - int count = method.parameterCount() + (isStatic ? 0 : 1); + int count = method.parameterCount(); for (int i = 0; i < count; ++i) { if (i > 0) { writer.append(',').ws(); } - writer.append('_').append(context.getParameterName(i + offset)); + writer.append('_').append(context.getParameterName(i + 1)); } writer.append(')').ws().append('{').softNewLine().indent(); @@ -68,7 +67,7 @@ public class JSBodyGenerator implements Generator { if (i > 0) { writer.append(',').ws(); } - writer.append('_').append(context.getParameterName(i + offset)); + writer.append('_').append(context.getParameterName(i + 1)); } writer.append(");").softNewLine(); writer.outdent().append("};").softNewLine(); @@ -81,7 +80,7 @@ public class JSBodyGenerator implements Generator { if (i > 0) { writer.append(',').ws(); } - writer.append(context.getParameterName(i + offset)); + writer.append(context.getParameterName(i + 1)); } writer.append(");").softNewLine(); }