diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/ClassDependencyListener.java b/classlib/src/main/java/org/teavm/classlib/java/lang/ClassDependencyListener.java index c49d83659..da2115848 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/ClassDependencyListener.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/ClassDependencyListener.java @@ -29,6 +29,9 @@ public class ClassDependencyListener implements DependencyPlugin { .linkClass(type.getName(), location) .initClass(location)); break; + case "getSimpleNameCacheLowLevel": + method.getResult().propagate(agent.getType("java.lang.String")); + break; } } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/ObjectDependencyPlugin.java b/classlib/src/main/java/org/teavm/classlib/java/lang/ObjectDependencyPlugin.java new file mode 100644 index 000000000..ac264bf72 --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/ObjectDependencyPlugin.java @@ -0,0 +1,32 @@ +/* + * Copyright 2018 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.dependency.DependencyAgent; +import org.teavm.dependency.DependencyPlugin; +import org.teavm.dependency.MethodDependency; +import org.teavm.model.CallLocation; + +public class ObjectDependencyPlugin implements DependencyPlugin { + @Override + public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) { + switch (method.getMethod().getName()) { + case "clone": + method.getVariable(0).connect(method.getResult()); + break; + } + } +} diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 348b7c330..3bdbff0fa 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -27,6 +27,7 @@ import java.util.Objects; import java.util.Set; import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.backend.javascript.spi.InjectedBy; +import org.teavm.classlib.PlatformDetector; import org.teavm.classlib.impl.DeclaringClassMetadataGenerator; import org.teavm.classlib.impl.reflection.Flags; import org.teavm.classlib.impl.reflection.JSClass; @@ -103,24 +104,24 @@ public class TClass extends TObject implements TAnnotatedElement { return Address.ofObject(this).toStructure().isSupertypeOf.apply(other); } - @DelegateTo("getNameLowLevel") - public TString getName() { - if (name == null) { - name = TString.wrap(Platform.getName(platformClass)); - } - return name; - } - @Unmanaged - private RuntimeObject getNameLowLevel() { - RuntimeClass runtimeClass = Address.ofObject(this).toStructure(); - return runtimeClass.name; + public TString getName() { + if (PlatformDetector.isLowLevel()) { + return TString.wrap(Platform.getName(platformClass)); + } else { + if (name == null) { + name = TString.wrap(Platform.getName(platformClass)); + } + return name; + } } public TString getSimpleName() { + TString simpleName = getSimpleNameCache(); if (simpleName == null) { if (isArray()) { simpleName = getComponentType().getSimpleName().concat(TString.wrap("[]")); + setSimpleNameCache(simpleName); return simpleName; } String name = Platform.getName(platformClass); @@ -137,10 +138,31 @@ public class TClass extends TObject implements TAnnotatedElement { } } simpleName = TString.wrap(name); + setSimpleNameCache(simpleName); } return simpleName; } + @DelegateTo("getSimpleNameCacheLowLevel") + private TString getSimpleNameCache() { + return simpleName; + } + + @Unmanaged + @PluggableDependency(ClassDependencyListener.class) + private RuntimeObject getSimpleNameCacheLowLevel() { + return Address.ofObject(this).toStructure().simpleName; + } + + private void setSimpleNameCache(TString value) { + simpleName = value; + } + + @Unmanaged + private void setSimpleNameCacheLowLevel(RuntimeObject object) { + Address.ofObject(this).toStructure().simpleName = object; + } + public boolean isPrimitive() { return Platform.isPrimitive(platformClass); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 8e78cb784..909017701 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -15,6 +15,7 @@ */ package org.teavm.classlib.java.lang; +import org.teavm.dependency.PluggableDependency; import org.teavm.interop.Address; import org.teavm.interop.Async; import org.teavm.interop.DelegateTo; @@ -223,6 +224,7 @@ public class TObject { @Override @DelegateTo("cloneLowLevel") + @PluggableDependency(ObjectDependencyPlugin.class) protected Object clone() throws TCloneNotSupportedException { if (!(this instanceof TCloneable) && Platform.getPlatformObject(this) .getPlatformClass().getMetadata().getArrayItem() == null) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index 389bb90fc..422416a27 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -29,6 +29,7 @@ import org.teavm.classlib.java.util.THashMap; import org.teavm.classlib.java.util.TLocale; import org.teavm.classlib.java.util.TMap; import org.teavm.classlib.java.util.regex.TPattern; +import org.teavm.interop.Unmanaged; public class TString extends TObject implements TSerializable, TComparable, TCharSequence { public static final TComparator CASE_INSENSITIVE_ORDER = (o1, o2) -> o1.compareToIgnoreCase(o2); @@ -578,6 +579,7 @@ public class TString extends TObject implements TSerializable, TComparable