mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +08:00
Improve <clinit> elimination:
* Generate clinit instruction instead of calling <clinit> directly * Rename annotation that indicates absence of side effects * Don't apply this annotation automatically to all JSBody methods
This commit is contained in:
parent
b8c73ae00c
commit
f33c90f778
@ -41,7 +41,7 @@ import org.teavm.classlib.java.lang.reflect.TModifier;
|
|||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
import org.teavm.jso.core.JSArray;
|
import org.teavm.jso.core.JSArray;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
@ -210,7 +210,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassGenerator.class)
|
@GeneratedBy(ClassGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native void createMetadata();
|
private static native void createMetadata();
|
||||||
|
|
||||||
public TField[] getFields() throws TSecurityException {
|
public TField[] getFields() throws TSecurityException {
|
||||||
|
@ -19,7 +19,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||||
import org.teavm.classlib.impl.Base64Impl;
|
import org.teavm.classlib.impl.Base64Impl;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSIndexer;
|
import org.teavm.jso.JSIndexer;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
@ -69,7 +69,7 @@ public abstract class TClassLoader extends TObject {
|
|||||||
private static native String resourceToString(JSObject resource);
|
private static native String resourceToString(JSObject resource);
|
||||||
|
|
||||||
@InjectedBy(ClassLoaderNativeGenerator.class)
|
@InjectedBy(ClassLoaderNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native ResourceContainer supplyResources();
|
private static native ResourceContainer supplyResources();
|
||||||
|
|
||||||
interface ResourceContainer extends JSObject {
|
interface ResourceContainer extends JSObject {
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public class TDouble extends TNumber implements TComparable<TDouble> {
|
public class TDouble extends TNumber implements TComparable<TDouble> {
|
||||||
public static final double POSITIVE_INFINITY = 1 / 0.0;
|
public static final double POSITIVE_INFINITY = 1 / 0.0;
|
||||||
public static final double NEGATIVE_INFINITY = -POSITIVE_INFINITY;
|
public static final double NEGATIVE_INFINITY = -POSITIVE_INFINITY;
|
||||||
@ -210,7 +210,7 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
|||||||
return (int) (h >>> 32) ^ (int) h;
|
return (int) (h >>> 32) ^ (int) h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int compare(double a, double b);
|
public static native int compare(double a, double b);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -228,18 +228,22 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
|||||||
|
|
||||||
@JSBody(params = "v", script = "return isNaN(v);")
|
@JSBody(params = "v", script = "return isNaN(v);")
|
||||||
@Import(module = "teavm", name = "isnan")
|
@Import(module = "teavm", name = "isnan")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isNaN(double v);
|
public static native boolean isNaN(double v);
|
||||||
|
|
||||||
@JSBody(script = "return NaN;")
|
@JSBody(script = "return NaN;")
|
||||||
@Import(module = "teavm", name = "TeaVM_getNaN")
|
@Import(module = "teavm", name = "TeaVM_getNaN")
|
||||||
|
@NoSideEffects
|
||||||
private static native double getNaN();
|
private static native double getNaN();
|
||||||
|
|
||||||
@JSBody(params = "v", script = "return !isFinite(v);")
|
@JSBody(params = "v", script = "return !isFinite(v);")
|
||||||
@Import(module = "teavm", name = "isinf")
|
@Import(module = "teavm", name = "isinf")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isInfinite(double v);
|
public static native boolean isInfinite(double v);
|
||||||
|
|
||||||
@JSBody(params = "v", script = "return isFinite(v);")
|
@JSBody(params = "v", script = "return isFinite(v);")
|
||||||
@Import(module = "teavm", name = "isfinite")
|
@Import(module = "teavm", name = "isfinite")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isFinite(double v);
|
public static native boolean isFinite(double v);
|
||||||
|
|
||||||
public static long doubleToRawLongBits(double value) {
|
public static long doubleToRawLongBits(double value) {
|
||||||
@ -248,10 +252,12 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
|||||||
|
|
||||||
@InjectedBy(DoubleGenerator.class)
|
@InjectedBy(DoubleGenerator.class)
|
||||||
@Import(name = "teavm_reinterpretDoubleToLong")
|
@Import(name = "teavm_reinterpretDoubleToLong")
|
||||||
|
@NoSideEffects
|
||||||
public static native long doubleToLongBits(double value);
|
public static native long doubleToLongBits(double value);
|
||||||
|
|
||||||
@InjectedBy(DoubleGenerator.class)
|
@InjectedBy(DoubleGenerator.class)
|
||||||
@Import(name = "teavm_reinterpretLongToDouble")
|
@Import(name = "teavm_reinterpretLongToDouble")
|
||||||
|
@NoSideEffects
|
||||||
public static native double longBitsToDouble(long bits);
|
public static native double longBitsToDouble(long bits);
|
||||||
|
|
||||||
public static String toHexString(double d) {
|
public static String toHexString(double d) {
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
|
|
||||||
public class TFloat extends TNumber implements TComparable<TFloat> {
|
public class TFloat extends TNumber implements TComparable<TFloat> {
|
||||||
@ -92,18 +92,22 @@ public class TFloat extends TNumber implements TComparable<TFloat> {
|
|||||||
|
|
||||||
@JSBody(params = "v", script = "return isNaN(v);")
|
@JSBody(params = "v", script = "return isNaN(v);")
|
||||||
@Import(module = "teavm", name = "isnan")
|
@Import(module = "teavm", name = "isnan")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isNaN(float v);
|
public static native boolean isNaN(float v);
|
||||||
|
|
||||||
@JSBody(params = "v", script = "return !isFinite(v);")
|
@JSBody(params = "v", script = "return !isFinite(v);")
|
||||||
@Import(module = "teavm", name = "isinf")
|
@Import(module = "teavm", name = "isinf")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isInfinite(float v);
|
public static native boolean isInfinite(float v);
|
||||||
|
|
||||||
@JSBody(params = "v", script = "return isFinite(v);")
|
@JSBody(params = "v", script = "return isFinite(v);")
|
||||||
@Import(module = "teavm", name = "isfinite")
|
@Import(module = "teavm", name = "isfinite")
|
||||||
|
@NoSideEffects
|
||||||
public static native boolean isFinite(float v);
|
public static native boolean isFinite(float v);
|
||||||
|
|
||||||
@JSBody(script = "return NaN;")
|
@JSBody(script = "return NaN;")
|
||||||
@Import(module = "teavm", name = "TeaVM_getNaN")
|
@Import(module = "teavm", name = "TeaVM_getNaN")
|
||||||
|
@NoSideEffects
|
||||||
private static native float getNaN();
|
private static native float getNaN();
|
||||||
|
|
||||||
public static float parseFloat(TString string) throws TNumberFormatException {
|
public static float parseFloat(TString string) throws TNumberFormatException {
|
||||||
@ -238,7 +242,7 @@ public class TFloat extends TNumber implements TComparable<TFloat> {
|
|||||||
return isInfinite(value);
|
return isInfinite(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int compare(float f1, float f2);
|
public static native int compare(float f1, float f2);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -252,10 +256,12 @@ public class TFloat extends TNumber implements TComparable<TFloat> {
|
|||||||
|
|
||||||
@JSBody(params = "value", script = "return $rt_floatToIntBits(value);")
|
@JSBody(params = "value", script = "return $rt_floatToIntBits(value);")
|
||||||
@Import(name = "teavm_reinterpretFloatToInt")
|
@Import(name = "teavm_reinterpretFloatToInt")
|
||||||
|
@NoSideEffects
|
||||||
public static native int floatToIntBits(float value);
|
public static native int floatToIntBits(float value);
|
||||||
|
|
||||||
@JSBody(params = "bits", script = "return $rt_intBitsToFloat(bits);")
|
@JSBody(params = "bits", script = "return $rt_intBitsToFloat(bits);")
|
||||||
@Import(name = "teavm_reinterpretIntToFloat")
|
@Import(name = "teavm_reinterpretIntToFloat")
|
||||||
|
@NoSideEffects
|
||||||
public static native float intBitsToFloat(int bits);
|
public static native float intBitsToFloat(int bits);
|
||||||
|
|
||||||
public static String toHexString(float f) {
|
public static String toHexString(float f) {
|
||||||
|
@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang;
|
|||||||
|
|
||||||
import static org.teavm.classlib.impl.IntegerUtil.toUnsignedLogRadixString;
|
import static org.teavm.classlib.impl.IntegerUtil.toUnsignedLogRadixString;
|
||||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
|
|
||||||
public class TInteger extends TNumber implements TComparable<TInteger> {
|
public class TInteger extends TNumber implements TComparable<TInteger> {
|
||||||
public static final int SIZE = 32;
|
public static final int SIZE = 32;
|
||||||
@ -252,7 +252,7 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
|
|||||||
return compare(value, other.value);
|
return compare(value, other.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int compare(int x, int y);
|
public static native int compare(int x, int y);
|
||||||
|
|
||||||
public static int numberOfLeadingZeros(int i) {
|
public static int numberOfLeadingZeros(int i) {
|
||||||
@ -358,10 +358,10 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InjectedBy(IntegerNativeGenerator.class)
|
@InjectedBy(IntegerNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int divideUnsigned(int dividend, int divisor);
|
public static native int divideUnsigned(int dividend, int divisor);
|
||||||
|
|
||||||
@InjectedBy(IntegerNativeGenerator.class)
|
@InjectedBy(IntegerNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int remainderUnsigned(int dividend, int divisor);
|
public static native int remainderUnsigned(int dividend, int divisor);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang;
|
|||||||
|
|
||||||
import static org.teavm.classlib.impl.IntegerUtil.toUnsignedLogRadixString;
|
import static org.teavm.classlib.impl.IntegerUtil.toUnsignedLogRadixString;
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
|
|
||||||
public class TLong extends TNumber implements TComparable<TLong> {
|
public class TLong extends TNumber implements TComparable<TLong> {
|
||||||
public static final long MIN_VALUE = -0x8000000000000000L;
|
public static final long MIN_VALUE = -0x8000000000000000L;
|
||||||
@ -213,7 +213,7 @@ public class TLong extends TNumber implements TComparable<TLong> {
|
|||||||
return other instanceof TLong && ((TLong) other).value == value;
|
return other instanceof TLong && ((TLong) other).value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int compare(long a, long b);
|
public static native int compare(long a, long b);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -353,10 +353,10 @@ public class TLong extends TNumber implements TComparable<TLong> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(LongNativeGenerator.class)
|
@GeneratedBy(LongNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native long divideUnsigned(long dividend, long divisor);
|
public static native long divideUnsigned(long dividend, long divisor);
|
||||||
|
|
||||||
@GeneratedBy(LongNativeGenerator.class)
|
@GeneratedBy(LongNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native long remainderUnsigned(long dividend, long divisor);
|
public static native long remainderUnsigned(long dividend, long divisor);
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
|
import org.teavm.interop.NoSideEffects;
|
||||||
|
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public final class TMath extends TObject {
|
public final class TMath extends TObject {
|
||||||
public static final double E = 2.71828182845904523536;
|
public static final double E = 2.71828182845904523536;
|
||||||
public static final double PI = 3.14159265358979323846;
|
public static final double PI = 3.14159265358979323846;
|
||||||
|
@ -21,7 +21,7 @@ import org.teavm.interop.Address;
|
|||||||
import org.teavm.interop.Async;
|
import org.teavm.interop.Async;
|
||||||
import org.teavm.interop.AsyncCallback;
|
import org.teavm.interop.AsyncCallback;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Rename;
|
import org.teavm.interop.Rename;
|
||||||
import org.teavm.interop.Structure;
|
import org.teavm.interop.Structure;
|
||||||
import org.teavm.interop.Superclass;
|
import org.teavm.interop.Superclass;
|
||||||
@ -273,7 +273,7 @@ public class TObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("hashCodeLowLevelImpl")
|
@DelegateTo("hashCodeLowLevelImpl")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native int hashCodeLowLevel(TObject obj);
|
private static native int hashCodeLowLevel(TObject obj);
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
@ -282,7 +282,7 @@ public class TObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("setHashCodeLowLevelImpl")
|
@DelegateTo("setHashCodeLowLevelImpl")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native void setHashCodeLowLevel(TObject obj, int value);
|
private static native void setHashCodeLowLevel(TObject obj, int value);
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
@ -303,7 +303,7 @@ public class TObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("identityOrMonitorLowLevel")
|
@DelegateTo("identityOrMonitorLowLevel")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private native int identityOrMonitor();
|
private native int identityOrMonitor();
|
||||||
|
|
||||||
private static int identityOrMonitorLowLevel(RuntimeObject object) {
|
private static int identityOrMonitorLowLevel(RuntimeObject object) {
|
||||||
@ -311,7 +311,7 @@ public class TObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("setIdentityLowLevel")
|
@DelegateTo("setIdentityLowLevel")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
native void setIdentity(int id);
|
native void setIdentity(int id);
|
||||||
|
|
||||||
private static void setIdentityLowLevel(RuntimeObject object, int id) {
|
private static void setIdentityLowLevel(RuntimeObject object, int id) {
|
||||||
|
@ -30,7 +30,7 @@ import org.teavm.classlib.java.util.TFormatter;
|
|||||||
import org.teavm.classlib.java.util.TLocale;
|
import org.teavm.classlib.java.util.TLocale;
|
||||||
import org.teavm.classlib.java.util.regex.TPattern;
|
import org.teavm.classlib.java.util.regex.TPattern;
|
||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
|
|
||||||
public class TString extends TObject implements TSerializable, TComparable<TString>, TCharSequence {
|
public class TString extends TObject implements TSerializable, TComparable<TString>, TCharSequence {
|
||||||
public static final TComparator<TString> CASE_INSENSITIVE_ORDER = (o1, o2) -> o1.compareToIgnoreCase(o2);
|
public static final TComparator<TString> CASE_INSENSITIVE_ORDER = (o1, o2) -> o1.compareToIgnoreCase(o2);
|
||||||
@ -628,7 +628,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
|||||||
|
|
||||||
@GeneratedBy(StringNativeGenerator.class)
|
@GeneratedBy(StringNativeGenerator.class)
|
||||||
@PluggableDependency(StringNativeGenerator.class)
|
@PluggableDependency(StringNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public native TString intern();
|
public native TString intern();
|
||||||
|
|
||||||
public boolean matches(String regex) {
|
public boolean matches(String regex) {
|
||||||
|
@ -25,8 +25,8 @@ import org.teavm.classlib.java.io.TPrintStream;
|
|||||||
import org.teavm.classlib.java.lang.reflect.TArray;
|
import org.teavm.classlib.java.lang.reflect.TArray;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
import org.teavm.runtime.Allocator;
|
import org.teavm.runtime.Allocator;
|
||||||
import org.teavm.runtime.GC;
|
import org.teavm.runtime.GC;
|
||||||
@ -104,7 +104,7 @@ public final class TSystem extends TObject {
|
|||||||
|
|
||||||
@GeneratedBy(SystemNativeGenerator.class)
|
@GeneratedBy(SystemNativeGenerator.class)
|
||||||
@DelegateTo("doArrayCopyLowLevel")
|
@DelegateTo("doArrayCopyLowLevel")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
|
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
@ -126,7 +126,7 @@ public final class TSystem extends TObject {
|
|||||||
|
|
||||||
@DelegateTo("currentTimeMillisLowLevel")
|
@DelegateTo("currentTimeMillisLowLevel")
|
||||||
@GeneratedBy(SystemNativeGenerator.class)
|
@GeneratedBy(SystemNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native long currentTimeMillis();
|
public static native long currentTimeMillis();
|
||||||
|
|
||||||
private static long currentTimeMillisLowLevel() {
|
private static long currentTimeMillisLowLevel() {
|
||||||
|
@ -24,7 +24,7 @@ import org.teavm.classlib.java.lang.TNullPointerException;
|
|||||||
import org.teavm.classlib.java.lang.TObject;
|
import org.teavm.classlib.java.lang.TObject;
|
||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.runtime.Allocator;
|
import org.teavm.runtime.Allocator;
|
||||||
@ -36,7 +36,7 @@ public final class TArray extends TObject {
|
|||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@PluggableDependency(ArrayNativeGenerator.class)
|
@PluggableDependency(ArrayNativeGenerator.class)
|
||||||
@DelegateTo("getLengthLowLevel")
|
@DelegateTo("getLengthLowLevel")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
public static native int getLength(TObject array) throws TIllegalArgumentException;
|
public static native int getLength(TObject array) throws TIllegalArgumentException;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -65,7 +65,7 @@ public final class TArray extends TObject {
|
|||||||
|
|
||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@DelegateTo("newInstanceLowLevel")
|
@DelegateTo("newInstanceLowLevel")
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native TObject newInstanceImpl(PlatformClass componentType, int length);
|
private static native TObject newInstanceImpl(PlatformClass componentType, int length);
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -92,11 +92,11 @@ public final class TArray extends TObject {
|
|||||||
|
|
||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@PluggableDependency(ArrayNativeGenerator.class)
|
@PluggableDependency(ArrayNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native TObject getImpl(TObject array, int index);
|
private static native TObject getImpl(TObject array, int index);
|
||||||
|
|
||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@PluggableDependency(ArrayNativeGenerator.class)
|
@PluggableDependency(ArrayNativeGenerator.class)
|
||||||
@DoesNotModifyStaticFields
|
@NoSideEffects
|
||||||
private static native void setImpl(TObject array, int index, TObject value);
|
private static native void setImpl(TObject array, int index, TObject value);
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ public class Renderer implements RenderingManager {
|
|||||||
try {
|
try {
|
||||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(CLINIT_METHOD);
|
MethodReader clinit = classSource.get(cls.getName()).getMethod(CLINIT_METHOD);
|
||||||
|
|
||||||
if (clinit != null && context.isDynamicInitializer(cls.getName())) {
|
if (clinit != null) {
|
||||||
renderCallClinit(clinit, cls);
|
renderCallClinit(clinit, cls);
|
||||||
}
|
}
|
||||||
if (!cls.getClassHolder().getModifiers().contains(ElementModifier.INTERFACE)) {
|
if (!cls.getClassHolder().getModifiers().contains(ElementModifier.INTERFACE)) {
|
||||||
|
@ -27,7 +27,7 @@ import java.util.Set;
|
|||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.dependency.MethodDependencyInfo;
|
import org.teavm.dependency.MethodDependencyInfo;
|
||||||
import org.teavm.dependency.ValueDependencyInfo;
|
import org.teavm.dependency.ValueDependencyInfo;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.model.BasicBlockReader;
|
import org.teavm.model.BasicBlockReader;
|
||||||
import org.teavm.model.ClassHierarchy;
|
import org.teavm.model.ClassHierarchy;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
@ -155,15 +155,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||||||
InstructionAnalyzer reader = new InstructionAnalyzer(currentClass, methodInfo);
|
InstructionAnalyzer reader = new InstructionAnalyzer(currentClass, methodInfo);
|
||||||
ProgramReader program = method.getProgram();
|
ProgramReader program = method.getProgram();
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
methodInfo.anyFieldModified = true;
|
methodInfo.anyFieldModified = hasSideEffects(method);
|
||||||
if (method.getAnnotations().get(DoesNotModifyStaticFields.class.getName()) != null) {
|
|
||||||
methodInfo.anyFieldModified = false;
|
|
||||||
} else {
|
|
||||||
ClassReader containingClass = classes.get(method.getOwnerName());
|
|
||||||
if (containingClass.getAnnotations().get(DoesNotModifyStaticFields.class.getName()) != null) {
|
|
||||||
methodInfo.anyFieldModified = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (BasicBlockReader block : program.getBasicBlocks()) {
|
for (BasicBlockReader block : program.getBasicBlocks()) {
|
||||||
block.readAllInstructions(reader);
|
block.readAllInstructions(reader);
|
||||||
@ -180,6 +172,18 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||||||
return methodInfo;
|
return methodInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasSideEffects(MethodReader method) {
|
||||||
|
if (method.getAnnotations().get(NoSideEffects.class.getName()) != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ClassReader containingClass = classes.get(method.getOwnerName());
|
||||||
|
if (containingClass.getAnnotations().get(NoSideEffects.class.getName()) != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
class InstructionAnalyzer extends AbstractInstructionReader {
|
class InstructionAnalyzer extends AbstractInstructionReader {
|
||||||
String currentClass;
|
String currentClass;
|
||||||
MethodInfo methodInfo;
|
MethodInfo methodInfo;
|
||||||
|
@ -75,7 +75,6 @@ import org.teavm.model.ValueType;
|
|||||||
import org.teavm.model.analysis.ClassInitializerAnalysis;
|
import org.teavm.model.analysis.ClassInitializerAnalysis;
|
||||||
import org.teavm.model.analysis.ClassInitializerInfo;
|
import org.teavm.model.analysis.ClassInitializerInfo;
|
||||||
import org.teavm.model.instructions.InitClassInstruction;
|
import org.teavm.model.instructions.InitClassInstruction;
|
||||||
import org.teavm.model.instructions.InvokeInstruction;
|
|
||||||
import org.teavm.model.optimization.ArrayUnwrapMotion;
|
import org.teavm.model.optimization.ArrayUnwrapMotion;
|
||||||
import org.teavm.model.optimization.ClassInitElimination;
|
import org.teavm.model.optimization.ClassInitElimination;
|
||||||
import org.teavm.model.optimization.ConstantConditionElimination;
|
import org.teavm.model.optimization.ConstantConditionElimination;
|
||||||
@ -523,9 +522,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||||||
BasicBlock block = program.basicBlockAt(0);
|
BasicBlock block = program.basicBlockAt(0);
|
||||||
Instruction first = block.getFirstInstruction();
|
Instruction first = block.getFirstInstruction();
|
||||||
for (String className : classInitializerInfo.getInitializationOrder()) {
|
for (String className : classInitializerInfo.getInitializationOrder()) {
|
||||||
InvokeInstruction invoke = new InvokeInstruction();
|
InitClassInstruction clinit = new InitClassInstruction();
|
||||||
invoke.setMethod(new MethodReference(className, "<clinit>", ValueType.VOID));
|
clinit.setClassName(className);
|
||||||
first.insertPrevious(invoke);
|
first.insertPrevious(clinit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,5 +22,5 @@ import java.lang.annotation.Target;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||||
public @interface DoesNotModifyStaticFields {
|
public @interface NoSideEffects {
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ import org.mozilla.javascript.ast.FunctionNode;
|
|||||||
import org.teavm.backend.javascript.rendering.JSParser;
|
import org.teavm.backend.javascript.rendering.JSParser;
|
||||||
import org.teavm.cache.IncrementalDependencyRegistration;
|
import org.teavm.cache.IncrementalDependencyRegistration;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Sync;
|
import org.teavm.interop.Sync;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSByRef;
|
import org.teavm.jso.JSByRef;
|
||||||
@ -654,7 +654,9 @@ class JSClassProcessor {
|
|||||||
MethodHolder proxyMethod = new MethodHolder(proxyRef.getDescriptor());
|
MethodHolder proxyMethod = new MethodHolder(proxyRef.getDescriptor());
|
||||||
proxyMethod.getModifiers().add(ElementModifier.NATIVE);
|
proxyMethod.getModifiers().add(ElementModifier.NATIVE);
|
||||||
proxyMethod.getModifiers().add(ElementModifier.STATIC);
|
proxyMethod.getModifiers().add(ElementModifier.STATIC);
|
||||||
proxyMethod.getAnnotations().add(new AnnotationHolder(DoesNotModifyStaticFields.class.getName()));
|
if (method.getAnnotations().get(NoSideEffects.class.getName()) != null) {
|
||||||
|
proxyMethod.getAnnotations().add(new AnnotationHolder(NoSideEffects.class.getName()));
|
||||||
|
}
|
||||||
boolean inline = repository.inlineMethods.contains(methodRef);
|
boolean inline = repository.inlineMethods.contains(methodRef);
|
||||||
AnnotationHolder generatorAnnot = new AnnotationHolder(inline
|
AnnotationHolder generatorAnnot = new AnnotationHolder(inline
|
||||||
? DynamicInjector.class.getName() : DynamicGenerator.class.getName());
|
? DynamicInjector.class.getName() : DynamicGenerator.class.getName());
|
||||||
|
@ -21,6 +21,7 @@ import org.teavm.backend.javascript.spi.InjectedBy;
|
|||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.PlatformMarker;
|
import org.teavm.interop.PlatformMarker;
|
||||||
import org.teavm.interop.PlatformMarkers;
|
import org.teavm.interop.PlatformMarkers;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
@ -42,10 +43,12 @@ public final class Platform {
|
|||||||
|
|
||||||
@InjectedBy(PlatformGenerator.class)
|
@InjectedBy(PlatformGenerator.class)
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
|
@NoSideEffects
|
||||||
public static native PlatformObject getPlatformObject(Object obj);
|
public static native PlatformObject getPlatformObject(Object obj);
|
||||||
|
|
||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
@NoSideEffects
|
||||||
public static native Object clone(Object obj);
|
public static native Object clone(Object obj);
|
||||||
|
|
||||||
@DelegateTo("isInstanceLowLevel")
|
@DelegateTo("isInstanceLowLevel")
|
||||||
@ -61,6 +64,7 @@ public final class Platform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(params = "object", script = "return typeof object === 'undefined';")
|
@JSBody(params = "object", script = "return typeof object === 'undefined';")
|
||||||
|
@NoSideEffects
|
||||||
private static native boolean isUndefined(JSObject object);
|
private static native boolean isUndefined(JSObject object);
|
||||||
|
|
||||||
@DelegateTo("isAssignableLowLevel")
|
@DelegateTo("isAssignableLowLevel")
|
||||||
@ -86,9 +90,11 @@ public final class Platform {
|
|||||||
@InjectedBy(PlatformGenerator.class)
|
@InjectedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
|
@NoSideEffects
|
||||||
public static native Class<?> asJavaClass(PlatformObject obj);
|
public static native Class<?> asJavaClass(PlatformObject obj);
|
||||||
|
|
||||||
@JSBody(script = "return $rt_nextId();")
|
@JSBody(script = "return $rt_nextId();")
|
||||||
|
@NoSideEffects
|
||||||
public static native int nextObjectId();
|
public static native int nextObjectId();
|
||||||
|
|
||||||
public static <T> T newInstance(PlatformClass cls) {
|
public static <T> T newInstance(PlatformClass cls) {
|
||||||
@ -100,6 +106,7 @@ public final class Platform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@NoSideEffects
|
||||||
private static native void prepareNewInstance();
|
private static native void prepareNewInstance();
|
||||||
|
|
||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
@ -108,6 +115,7 @@ public final class Platform {
|
|||||||
|
|
||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
@NoSideEffects
|
||||||
public static native PlatformClass lookupClass(String name);
|
public static native PlatformClass lookupClass(String name);
|
||||||
|
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
@ -133,6 +141,7 @@ public final class Platform {
|
|||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
@DelegateTo("getEnumConstantsLowLevel")
|
@DelegateTo("getEnumConstantsLowLevel")
|
||||||
|
@NoSideEffects
|
||||||
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
|
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
|
||||||
|
|
||||||
private static Enum<?>[] getEnumConstantsLowLevel(PlatformClass cls) {
|
private static Enum<?>[] getEnumConstantsLowLevel(PlatformClass cls) {
|
||||||
@ -194,7 +203,6 @@ public final class Platform {
|
|||||||
Window.clearTimeout(id);
|
Window.clearTimeout(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(script = "return [];")
|
|
||||||
public static <T> PlatformQueue<T> createQueue() {
|
public static <T> PlatformQueue<T> createQueue() {
|
||||||
if (isLowLevel()) {
|
if (isLowLevel()) {
|
||||||
return new LowLevelQueue<>();
|
return new LowLevelQueue<>();
|
||||||
@ -204,6 +212,7 @@ public final class Platform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(script = "return [];")
|
@JSBody(script = "return [];")
|
||||||
|
@NoSideEffects
|
||||||
private static native <T> PlatformQueue<T> createQueueJs();
|
private static native <T> PlatformQueue<T> createQueueJs();
|
||||||
|
|
||||||
public static PlatformString stringFromCharCode(int charCode) {
|
public static PlatformString stringFromCharCode(int charCode) {
|
||||||
|
@ -18,7 +18,7 @@ package org.teavm.platform.plugin;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.interop.DoesNotModifyStaticFields;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.model.AccessLevel;
|
import org.teavm.model.AccessLevel;
|
||||||
import org.teavm.model.AnnotationHolder;
|
import org.teavm.model.AnnotationHolder;
|
||||||
import org.teavm.model.AnnotationValue;
|
import org.teavm.model.AnnotationValue;
|
||||||
@ -68,8 +68,8 @@ class MetadataProviderTransformer implements ClassHolderTransformer {
|
|||||||
MetadataProviderNativeGenerator.class.getName())));
|
MetadataProviderNativeGenerator.class.getName())));
|
||||||
createMethod.getAnnotations().add(genAnnot);
|
createMethod.getAnnotations().add(genAnnot);
|
||||||
ModelUtils.copyAnnotations(method.getAnnotations(), createMethod.getAnnotations());
|
ModelUtils.copyAnnotations(method.getAnnotations(), createMethod.getAnnotations());
|
||||||
if (createMethod.getAnnotations().get(DoesNotModifyStaticFields.class.getName()) == null) {
|
if (createMethod.getAnnotations().get(NoSideEffects.class.getName()) == null) {
|
||||||
createMethod.getAnnotations().add(new AnnotationHolder(DoesNotModifyStaticFields.class.getName()));
|
createMethod.getAnnotations().add(new AnnotationHolder(NoSideEffects.class.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationHolder refAnnot = new AnnotationHolder(MetadataProviderRef.class.getName());
|
AnnotationHolder refAnnot = new AnnotationHolder(MetadataProviderRef.class.getName());
|
||||||
|
@ -37,7 +37,7 @@ interface TeaVMTestConfiguration<T extends TeaVMTarget> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(TeaVM vm) {
|
public void apply(TeaVM vm) {
|
||||||
vm.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE);
|
vm.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user