diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSArray.java b/jso/apis/src/main/java/org/teavm/jso/core/JSArray.java index 206a36e90..1ea7c5e51 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSArray.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSArray.java @@ -18,10 +18,9 @@ package org.teavm.jso.core; import org.teavm.interop.NoSideEffects; import org.teavm.jso.JSBody; import org.teavm.jso.JSIndexer; -import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; -public abstract class JSArray implements JSArrayReader { +public abstract class JSArray implements JSArrayReader { private JSArray() { } @@ -85,18 +84,18 @@ public abstract class JSArray implements JSArrayReader { @JSBody(script = "return new Array();") @NoSideEffects - public static native JSArray create(); + public static native JSArray create(); @JSBody(params = "size", script = "return new Array(size);") @NoSideEffects - public static native JSArray create(int size); + public static native JSArray create(int size); @JSBody(params = "object", script = "return Array.isArray(object);") @NoSideEffects - public static native boolean isArray(JSObject object); + public static native boolean isArray(Object object); @SafeVarargs - public static JSArray of(S... items) { + public static JSArray of(S... items) { JSArray array = create(items.length); for (int i = 0; i < items.length; ++i) { array.set(i, items[i]); diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSArrayReader.java b/jso/apis/src/main/java/org/teavm/jso/core/JSArrayReader.java index 706d92e09..16c69449d 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSArrayReader.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSArrayReader.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSIndexer; import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; -public interface JSArrayReader extends JSObject { +public interface JSArrayReader extends JSObject { @JSProperty @NoSideEffects int getLength(); diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSError.java b/jso/apis/src/main/java/org/teavm/jso/core/JSError.java index 5883eb14e..77e86ec44 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSError.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSError.java @@ -27,7 +27,7 @@ public abstract class JSError implements JSObject { + "} catch (e) {" + "return catchClause(e);" + "}") - public static native T catchNative(TryClause tryClause, CatchClause catchClause); + public static native T catchNative(TryClause tryClause, CatchClause catchClause); @JSBody(params = "object", script = "return object instanceof Error;") public static native boolean isError(JSObject object); @@ -42,12 +42,12 @@ public abstract class JSError implements JSObject { public abstract String getName(); @JSFunctor - public interface TryClause extends JSObject { + public interface TryClause extends JSObject { T run(); } @JSFunctor - public interface CatchClause extends JSObject { + public interface CatchClause extends JSObject { T accept(JSObject e); } } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistry.java b/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistry.java index 413fcc443..53eeca28a 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistry.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistry.java @@ -15,12 +15,18 @@ */ package org.teavm.jso.core; +import org.teavm.interop.NoSideEffects; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; public abstract class JSFinalizationRegistry implements JSObject { - public abstract void register(JSObject obj, JSObject token); + public abstract void register(Object obj, Object token); @JSBody(params = "consumer", script = "return new FinalizationRegistry(consumer);") public static native JSFinalizationRegistry create(JSFinalizationRegistryConsumer consumer); + + + @JSBody(script = "return typeof FinalizationRegistry !== 'undefined';") + @NoSideEffects + public static native boolean isSupported(); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistryConsumer.java b/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistryConsumer.java index 1201dc8a3..91c91df1f 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistryConsumer.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSFinalizationRegistryConsumer.java @@ -20,5 +20,5 @@ import org.teavm.jso.JSObject; @JSFunctor public interface JSFinalizationRegistryConsumer extends JSObject { - void accept(JSObject obj); + void accept(Object obj); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSFunction.java b/jso/apis/src/main/java/org/teavm/jso/core/JSFunction.java index 9a5df7a23..33eb3d1e3 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSFunction.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSFunction.java @@ -19,33 +19,31 @@ import org.teavm.jso.JSByRef; import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; -public interface JSFunction extends JSObject { +public abstract class JSFunction implements JSObject { @JSProperty - int getLength(); + public abstract int getLength(); @JSProperty - String getName(); + public abstract String getName(); - JSObject call(JSObject thisArg); + public abstract Object call(Object thisArg); - JSObject call(JSObject thisArg, JSObject a); + public abstract Object call(Object thisArg, Object a); - JSObject call(JSObject thisArg, JSObject a, JSObject b); + public abstract Object call(Object thisArg, Object a, Object b); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c); + public abstract Object call(Object thisArg, Object a, Object b, Object c); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, - JSObject d); + public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e); + public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f); + public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, - JSObject g); + public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f, Object g); - JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, - JSObject g, JSObject h); + public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f, Object g, + Object h); - JSObject apply(JSObject thisArg, @JSByRef JSObject[] arguments); + public abstract Object apply(Object thisArg, @JSByRef Object[] arguments); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSMapLike.java b/jso/apis/src/main/java/org/teavm/jso/core/JSMapLike.java index 7fb0808d7..49705a2d2 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSMapLike.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSMapLike.java @@ -18,7 +18,7 @@ package org.teavm.jso.core; import org.teavm.jso.JSIndexer; import org.teavm.jso.JSObject; -public interface JSMapLike extends JSObject { +public interface JSMapLike extends JSObject { @JSIndexer T get(String key); diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSObjects.java b/jso/apis/src/main/java/org/teavm/jso/core/JSObjects.java index b5d3dcc4f..e33d08aa3 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSObjects.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSObjects.java @@ -25,11 +25,11 @@ public final class JSObjects { @JSBody(params = "object", script = "return Object.getOwnPropertyNames(object);") @NoSideEffects - public static native String[] getOwnPropertyNames(JSObject object); + public static native String[] getOwnPropertyNames(Object object); @JSBody(params = "object", script = "return Object.keys(object);") @NoSideEffects - public static native String[] keys(JSObject object); + public static native String[] keys(Object object); @JSBody(params = "object", script = "return Object.values(object);") @NoSideEffects @@ -45,7 +45,7 @@ public final class JSObjects { @JSBody(params = "object", script = "return typeof object === 'undefined';") @NoSideEffects - public static native boolean isUndefined(JSObject object); + public static native boolean isUndefined(Object object); @JSBody(script = "return void 0;") @NoSideEffects @@ -53,16 +53,16 @@ public final class JSObjects { @JSBody(params = "object", script = "return typeof object;") @NoSideEffects - public static native String typeOf(JSObject object); + public static native String typeOf(Object object); @JSBody(params = "object", script = "return object.toString();") - public static native String toString(JSObject object); + public static native String toString(Object object); @JSBody(params = { "object", "name" }, script = "return name in object;") @NoSideEffects - public static native boolean hasProperty(JSObject object, String name); + public static native boolean hasProperty(Object object, String name); @JSBody(params = "object", script = "return Object.getPrototypeOf(object);") @NoSideEffects - public static native JSObject getPrototypeOf(JSObject object); + public static native JSObject getPrototypeOf(Object object); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSSortFunction.java b/jso/apis/src/main/java/org/teavm/jso/core/JSSortFunction.java index 09cefca0f..5bd567497 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSSortFunction.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSSortFunction.java @@ -16,15 +16,9 @@ package org.teavm.jso.core; import org.teavm.jso.JSFunctor; -import org.teavm.jso.JSObject; -/** - * - * @author Alexey Andreev - * @param - */ @JSFunctor @FunctionalInterface -public interface JSSortFunction { +public interface JSSortFunction { int compare(T a, T b); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSSymbol.java b/jso/apis/src/main/java/org/teavm/jso/core/JSSymbol.java index 07de90884..d528693e2 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSSymbol.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSSymbol.java @@ -19,14 +19,14 @@ import org.teavm.interop.NoSideEffects; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; -public abstract class JSSymbol implements JSObject { +public abstract class JSSymbol implements JSObject { @JSBody(params = "name", script = "return Symbol(name);") - public static native JSSymbol create(String name); + public static native JSSymbol create(String name); @JSBody(params = "obj", script = "return obj[this];") - public native T get(JSObject obj); + public native T get(Object obj); @JSBody(params = { "obj", "value" }, script = "obj[this] = value;") @NoSideEffects - public native void set(JSObject obj, T value); + public native void set(Object obj, T value); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSWeakMap.java b/jso/apis/src/main/java/org/teavm/jso/core/JSWeakMap.java index 8f00bd8e7..196ffe72b 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSWeakMap.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSWeakMap.java @@ -19,7 +19,7 @@ import org.teavm.interop.NoSideEffects; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; -public abstract class JSWeakMap implements JSObject { +public abstract class JSWeakMap implements JSObject { public abstract V get(K key); public abstract boolean has(K key); @@ -30,5 +30,9 @@ public abstract class JSWeakMap implemen @JSBody(script = "return new WeakMap();") @NoSideEffects - public static native JSWeakMap create(); + public static native JSWeakMap create(); + + @JSBody(script = "return typeof WeakMap !== 'undefined';") + @NoSideEffects + public static native boolean isSupported(); } diff --git a/jso/apis/src/main/java/org/teavm/jso/core/JSWeakRef.java b/jso/apis/src/main/java/org/teavm/jso/core/JSWeakRef.java index b90df6ba7..98680ff04 100644 --- a/jso/apis/src/main/java/org/teavm/jso/core/JSWeakRef.java +++ b/jso/apis/src/main/java/org/teavm/jso/core/JSWeakRef.java @@ -19,12 +19,12 @@ import org.teavm.interop.NoSideEffects; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; -public abstract class JSWeakRef implements JSObject { +public abstract class JSWeakRef implements JSObject { public abstract T deref(); @JSBody(params = "value", script = "return new WeakRef(value);") @NoSideEffects - public static native JSWeakRef create(T value); + public static native JSWeakRef create(T value); @JSBody(script = "return typeof WeakRef !== 'undefined';") @NoSideEffects diff --git a/jso/apis/src/main/java/org/teavm/jso/dom/events/MessageEvent.java b/jso/apis/src/main/java/org/teavm/jso/dom/events/MessageEvent.java index 271f9b24a..64715f67e 100644 --- a/jso/apis/src/main/java/org/teavm/jso/dom/events/MessageEvent.java +++ b/jso/apis/src/main/java/org/teavm/jso/dom/events/MessageEvent.java @@ -15,13 +15,12 @@ */ package org.teavm.jso.dom.events; -import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; import org.teavm.jso.typedarrays.ArrayBuffer; public interface MessageEvent extends Event { @JSProperty - JSObject getData(); + Object getData(); @JSProperty("data") String getDataAsString(); diff --git a/jso/apis/src/main/java/org/teavm/jso/workers/MessagePort.java b/jso/apis/src/main/java/org/teavm/jso/workers/MessagePort.java index 2bad1ed89..be6eb97cb 100644 --- a/jso/apis/src/main/java/org/teavm/jso/workers/MessagePort.java +++ b/jso/apis/src/main/java/org/teavm/jso/workers/MessagePort.java @@ -15,14 +15,13 @@ */ package org.teavm.jso.workers; -import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.dom.events.EventTarget; import org.teavm.jso.dom.events.MessageEvent; public interface MessagePort extends EventTarget { - void postMessage(JSObject message); + void postMessage(Object message); void start(); diff --git a/jso/apis/src/main/java/org/teavm/jso/workers/Worker.java b/jso/apis/src/main/java/org/teavm/jso/workers/Worker.java index ea00af0a5..95876f9a4 100644 --- a/jso/apis/src/main/java/org/teavm/jso/workers/Worker.java +++ b/jso/apis/src/main/java/org/teavm/jso/workers/Worker.java @@ -16,7 +16,6 @@ package org.teavm.jso.workers; import org.teavm.jso.JSBody; -import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.dom.events.MessageEvent; @@ -28,7 +27,7 @@ public abstract class Worker implements AbstractWorker { @JSProperty("onmessage") public abstract void onMessage(EventListener listener); - public abstract void postMessage(JSObject message); + public abstract void postMessage(Object message); public abstract void terminate(); } diff --git a/jso/impl/src/main/java/org/teavm/jso/impl/JSWrapper.java b/jso/impl/src/main/java/org/teavm/jso/impl/JSWrapper.java index 9c5ab12c0..1978ca723 100644 --- a/jso/impl/src/main/java/org/teavm/jso/impl/JSWrapper.java +++ b/jso/impl/src/main/java/org/teavm/jso/impl/JSWrapper.java @@ -62,37 +62,37 @@ public final class JSWrapper { if (wrappers != null) { var type = JSObjects.typeOf(js); if (type.equals("object") || type.equals("function")) { - var existingRef = wrappers.get(js); - var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined(); + var existingRef = get(wrappers, js); + var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined(); if (JSObjects.isUndefined(existing)) { var wrapper = new JSWrapper(js); - wrappers.set(js, JSWeakRef.create(wrapperToJs(wrapper))); + set(wrappers, js, createWeakRef(wrapperToJs(wrapper))); return wrapper; } else { return jsToWrapper(existing); } } else if (type.equals("string")) { var jsString = (JSString) js; - var existingRef = stringWrappers.get(jsString); - var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined(); + var existingRef = get(stringWrappers, jsString); + var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined(); if (JSObjects.isUndefined(existing)) { var wrapper = new JSWrapper(js); var wrapperAsJs = wrapperToJs(wrapper); - stringWrappers.set(jsString, JSWeakRef.create(wrapperAsJs)); - stringFinalizationRegistry.register(wrapperAsJs, jsString); + set(stringWrappers, jsString, createWeakRef(wrapperAsJs)); + register(stringFinalizationRegistry, wrapperAsJs, jsString); return wrapper; } else { return jsToWrapper(existing); } } else if (type.equals("number")) { var jsNumber = (JSNumber) js; - var existingRef = numberWrappers.get(jsNumber); - var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined(); + var existingRef = get(numberWrappers, jsNumber); + var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined(); if (JSObjects.isUndefined(existing)) { var wrapper = new JSWrapper(js); var wrapperAsJs = wrapperToJs(wrapper); - numberWrappers.set(jsNumber, JSWeakRef.create(wrapperAsJs)); - numberFinalizationRegistry.register(wrapperAsJs, jsNumber); + set(numberWrappers, jsNumber, createWeakRef(wrapperAsJs)); + register(numberFinalizationRegistry, wrapperAsJs, jsNumber); return wrapper; } else { return jsToWrapper(existing); @@ -102,6 +102,37 @@ public final class JSWrapper { return new JSWrapper(js); } + @JSBody(params = "target", script = "return new WeakRef(target);") + @NoSideEffects + private static native JSWeakRef createWeakRef(JSObject target); + + @JSBody(params = "target", script = "return target.deref();") + @NoSideEffects + private static native JSObject deref(JSWeakRef target); + + @JSBody(params = { "registry", "target", "token" }, script = "return registry.register(target, token);") + @NoSideEffects + private static native void register(JSFinalizationRegistry registry, JSObject target, JSObject token); + + @JSBody(params = { "map", "key" }, script = "return map.get(key);") + @NoSideEffects + private static native JSWeakRef get(JSMap> map, JSObject key); + + @JSBody(params = { "map", "key", "value" }, script = "map.set(key, value);") + @NoSideEffects + private static native void set(JSMap> map, JSObject key, JSObject value); + + @JSBody(params = { "map", "key" }, script = "return map.get(key);") + @NoSideEffects + private static native JSWeakRef get(JSWeakMap> map, + JSObject key); + + @JSBody(params = { "map", "key", "value" }, script = "map.set(key, value);") + @NoSideEffects + private static native void set(JSWeakMap> map, JSObject key, + JSObject value); + + @NoSideEffects public static Object maybeWrap(Object o) { return o == null || isJava(o) ? o : wrap(o); }