Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.function.IntToDoubleFunction;
import java.util.function.IntToLongFunction;
import java.util.function.IntUnaryOperator;
import org.teavm.backend.javascript.spi.InjectedBy;
import org.teavm.classlib.PlatformDetector;
import org.teavm.classlib.java.lang.TIllegalArgumentException;
import org.teavm.classlib.java.lang.TMath;
import org.teavm.classlib.java.lang.TObject;
Expand All @@ -35,6 +37,8 @@
import org.teavm.classlib.java.util.stream.impl.TArrayStreamImpl;
import org.teavm.classlib.java.util.stream.intimpl.TArrayIntStreamImpl;
import org.teavm.classlib.java.util.stream.longimpl.TArrayLongStreamImpl;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSByRef;

public class TArrays extends TObject {
public static char[] copyOf(char[] array, int length) {
Expand Down Expand Up @@ -488,7 +492,14 @@ public static void sort(int[] a, int fromIndex, int toIndex) {
}
}

@JSBody(params = "arr", script="arr.sort();")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konsoletyper Like that?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. And also you don't need all these sortIntJS, sortLongJS, etc. It can be just sortJS with parameter typed overloaded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then there is a problem.

    @JSBody(params = {"arr", "cmp"}, script="arr.sort(cmp);")
    private static native void sortJS(@JSByRef Object/*[]*/ arr, TComparator<Object> cmp);

can't be compiled because

ERROR: Method java.util.Arrays.sortJS(Ljava/lang/Object;Ljava/util/Comparator;)V is not a proper native JavaScript method declaration: its 1th parameter is declared as JSByRef, which has incompatible type

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then for this case the only possible way is to generate the method. You can't just generate, you should also properly track dependencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to understand how pass comparator to native method. Closest example that I found was SystemNativeGenerator, but it doesn't handle functions. When I try to get JS function from wrapper accessing it via $compare1 property I get ClassCastException. Obviously I'm doing it wrong, but what is the correct way?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$compare1 property - where did you get this name? Did you try to dig deeper into TeaVM code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$compare1 property - where did you get this name?

I get this variable name when debugged in JS where compare function is hidden. Obviously it is not correct (even if it helped with normal code, I suppose it would be broken in minified code).

Did you try to dig deeper into TeaVM code?

I tried to find some example in existing generators/injectors but didn't manage to find any example where function is transformed from Java to JS. Documentation suggests to work with @JSFunctor when working with @JSBody, but it didn't help either. So this is my level of digging.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are using org.teavm.backend.javascript.templating.JavaScriptTemplateFactory. Did you try to look into it? Did you find references to org.teavm.backend.javascript.templating.TemplatingAstWriter from there? Did you try to understand the code and see how other generators using templates?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TemplatingAstWriter is used inside JavaScriptTemplate. Now after you pointed on it specifically I can see it.
I didn't look exactly at that class, but will take a look. Still, the closest example that I've seen is JSNativeGenerator, but it does the opposite from what I understand: allows to call JS functions from Java. If some reverse example was present, it would be great.

private static native void sortIntJS(@JSByRef int[] arr);

public static void sort(int[] a) {
if (PlatformDetector.isJavaScript()) {
sortIntJS(a);
return;
}
if (a.length == 0) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
public class ArraysTest {
@Test
public void arraySorted() {
int[] intArr = { 2, 5, 7, 3, 5, 6 };
Arrays.sort(intArr);
assertEquals(2, intArr[0]);
assertEquals(3, intArr[1]);
assertEquals(5, intArr[2]);
assertEquals(5, intArr[3]);
assertEquals(6, intArr[4]);
assertEquals(7, intArr[5]);
Integer[] array = { 2, 5, 7, 3, 5, 6 };
Arrays.sort(array);
assertEquals(Integer.valueOf(2), array[0]);
Expand Down
Loading