mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
js: support WeakReference
This commit is contained in:
parent
cd38447057
commit
22864c88f2
|
@ -19,7 +19,7 @@ public class TWeakReference<T> extends TReference<T> {
|
||||||
private T value;
|
private T value;
|
||||||
|
|
||||||
public TWeakReference(T value) {
|
public TWeakReference(T value) {
|
||||||
this.value = value;
|
this(value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TWeakReference(T value, @SuppressWarnings("unused") TReferenceQueue<T> queue) {
|
public TWeakReference(T value, @SuppressWarnings("unused") TReferenceQueue<T> queue) {
|
||||||
|
|
|
@ -21,6 +21,9 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
@ -50,6 +53,11 @@ import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||||
import org.teavm.backend.javascript.codegen.SourceWriterBuilder;
|
import org.teavm.backend.javascript.codegen.SourceWriterBuilder;
|
||||||
import org.teavm.backend.javascript.decompile.PreparedClass;
|
import org.teavm.backend.javascript.decompile.PreparedClass;
|
||||||
import org.teavm.backend.javascript.decompile.PreparedMethod;
|
import org.teavm.backend.javascript.decompile.PreparedMethod;
|
||||||
|
import org.teavm.backend.javascript.intrinsics.ref.ReferenceQueueGenerator;
|
||||||
|
import org.teavm.backend.javascript.intrinsics.ref.ReferenceQueueTransformer;
|
||||||
|
import org.teavm.backend.javascript.intrinsics.ref.WeakReferenceDependencyListener;
|
||||||
|
import org.teavm.backend.javascript.intrinsics.ref.WeakReferenceGenerator;
|
||||||
|
import org.teavm.backend.javascript.intrinsics.ref.WeakReferenceTransformer;
|
||||||
import org.teavm.backend.javascript.rendering.Renderer;
|
import org.teavm.backend.javascript.rendering.Renderer;
|
||||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||||
import org.teavm.backend.javascript.rendering.RenderingUtil;
|
import org.teavm.backend.javascript.rendering.RenderingUtil;
|
||||||
|
@ -143,7 +151,10 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ClassHolderTransformer> getTransformers() {
|
public List<ClassHolderTransformer> getTransformers() {
|
||||||
return Collections.emptyList();
|
return List.of(
|
||||||
|
new WeakReferenceTransformer(),
|
||||||
|
new ReferenceQueueTransformer()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,6 +165,16 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||||
@Override
|
@Override
|
||||||
public void setController(TeaVMTargetController controller) {
|
public void setController(TeaVMTargetController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
|
||||||
|
var weakRefGenerator = new WeakReferenceGenerator();
|
||||||
|
methodGenerators.put(new MethodReference(WeakReference.class, "<init>", Object.class,
|
||||||
|
ReferenceQueue.class, void.class), weakRefGenerator);
|
||||||
|
methodGenerators.put(new MethodReference(WeakReference.class, "get", Object.class), weakRefGenerator);
|
||||||
|
methodGenerators.put(new MethodReference(WeakReference.class, "clear", void.class), weakRefGenerator);
|
||||||
|
|
||||||
|
var refQueueGenerator = new ReferenceQueueGenerator();
|
||||||
|
methodGenerators.put(new MethodReference(ReferenceQueue.class, "<init>", void.class), refQueueGenerator);
|
||||||
|
methodGenerators.put(new MethodReference(ReferenceQueue.class, "poll", Reference.class), refQueueGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -321,6 +342,8 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dependencyAnalyzer.addDependencyListener(new WeakReferenceDependencyListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void includeStackTraceMethods(DependencyAnalyzer dependencyAnalyzer) {
|
public static void includeStackTraceMethods(DependencyAnalyzer dependencyAnalyzer) {
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.backend.javascript.intrinsics.ref;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||||
|
import org.teavm.backend.javascript.spi.Generator;
|
||||||
|
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public class ReferenceQueueGenerator implements Generator {
|
||||||
|
private static final FieldReference INNER_FIELD = new FieldReference(ReferenceQueue.class.getName(), "inner");
|
||||||
|
private static final FieldReference REGISTRY_FIELD = new FieldReference(ReferenceQueue.class.getName(),
|
||||||
|
"registry");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||||
|
switch (methodRef.getName()) {
|
||||||
|
case "<init>":
|
||||||
|
generateInitMethod(context, writer);
|
||||||
|
break;
|
||||||
|
case "poll":
|
||||||
|
generatePollMethod(context, writer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInitMethod(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append(context.getParameterName(0)).append(".").appendField(INNER_FIELD).ws().append("=")
|
||||||
|
.ws().append("[];").softNewLine();
|
||||||
|
writer.append(context.getParameterName(0)).append(".").appendField(REGISTRY_FIELD).ws().append("=")
|
||||||
|
.ws().append("new $rt_globals.FinalizationRegistry(x").ws().append("=>").ws()
|
||||||
|
.append(context.getParameterName(0)).appendField(INNER_FIELD)
|
||||||
|
.append(".push(x));").softNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generatePollMethod(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append("var value").ws().append("=").ws().append(context.getParameterName(0))
|
||||||
|
.append(".").appendField(INNER_FIELD).append(".shift();").softNewLine();
|
||||||
|
writer.append("return typeof value").ws().append("!==").ws().append("'undefined'").ws()
|
||||||
|
.append("?").ws().append("value").ws().append(":").ws().append("null;").softNewLine();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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.backend.javascript.intrinsics.ref;
|
||||||
|
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
import org.teavm.model.ClassHolderTransformerContext;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.FieldHolder;
|
||||||
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public class ReferenceQueueTransformer implements ClassHolderTransformer {
|
||||||
|
@Override
|
||||||
|
public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
|
||||||
|
if (cls.getName().equals(ReferenceQueue.class.getName())) {
|
||||||
|
var field = new FieldHolder("inner");
|
||||||
|
field.setType(ValueType.parse(Object.class));
|
||||||
|
cls.addField(field);
|
||||||
|
|
||||||
|
field = new FieldHolder("registry");
|
||||||
|
field.setType(ValueType.parse(Object.class));
|
||||||
|
cls.addField(field);
|
||||||
|
|
||||||
|
var pollMethod = cls.getMethod(new MethodDescriptor("poll", Reference.class));
|
||||||
|
pollMethod.setProgram(null);
|
||||||
|
pollMethod.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
|
||||||
|
var constructor = cls.getMethod(new MethodDescriptor("<init>", void.class));
|
||||||
|
constructor.setProgram(null);
|
||||||
|
constructor.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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.backend.javascript.intrinsics.ref;
|
||||||
|
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import org.teavm.dependency.AbstractDependencyListener;
|
||||||
|
import org.teavm.dependency.DependencyAgent;
|
||||||
|
import org.teavm.dependency.MethodDependency;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public class WeakReferenceDependencyListener extends AbstractDependencyListener {
|
||||||
|
@Override
|
||||||
|
public void methodReached(DependencyAgent agent, MethodDependency method) {
|
||||||
|
if (method.getMethod().getOwnerName().equals(WeakReference.class.getName())) {
|
||||||
|
referenceMethodReached(agent, method);
|
||||||
|
} else if (method.getMethod().getOwnerName().equals(ReferenceQueue.class.getName())) {
|
||||||
|
agent.linkField(new FieldReference(ReferenceQueue.class.getName(), "inner"));
|
||||||
|
agent.linkField(new FieldReference(ReferenceQueue.class.getName(), "registry"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void referenceMethodReached(DependencyAgent agent, MethodDependency method) {
|
||||||
|
switch (method.getMethod().getName()) {
|
||||||
|
case "<init>": {
|
||||||
|
if (method.getParameterCount() == 2) {
|
||||||
|
var field = agent.linkField(new FieldReference(method.getMethod().getOwnerName(), "value"));
|
||||||
|
method.getVariable(1).connect(field.getValue());
|
||||||
|
var pollResult = agent
|
||||||
|
.linkMethod(new MethodReference(ReferenceQueue.class, "poll", Reference.class))
|
||||||
|
.getResult();
|
||||||
|
method.getVariable(0).connect(pollResult);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "get": {
|
||||||
|
var field = agent.linkField(new FieldReference(method.getMethod().getOwnerName(), "value"));
|
||||||
|
field.getValue().connect(method.getResult());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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.backend.javascript.intrinsics.ref;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||||
|
import org.teavm.backend.javascript.spi.Generator;
|
||||||
|
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public class WeakReferenceGenerator implements Generator {
|
||||||
|
@Override
|
||||||
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||||
|
switch (methodRef.getName()) {
|
||||||
|
case "<init>":
|
||||||
|
generateConstructor(context, writer);
|
||||||
|
break;
|
||||||
|
case "get":
|
||||||
|
generateGet(context, writer);
|
||||||
|
break;
|
||||||
|
case "clear":
|
||||||
|
generateClear(context, writer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateConstructor(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append("var supported").ws().append("=").ws();
|
||||||
|
isSupported(writer).append(";").softNewLine();
|
||||||
|
writer.append("var value").ws().append("=").ws().append("supported").ws()
|
||||||
|
.append("?").ws().append("new $rt_globals.WeakRef(")
|
||||||
|
.append(context.getParameterName(1)).append(")").ws();
|
||||||
|
writer.append(":").ws().append(context.getParameterName(0)).append(";").softNewLine();
|
||||||
|
|
||||||
|
writer.append(context.getParameterName(0)).append(".")
|
||||||
|
.appendField(new FieldReference(WeakReference.class.getName(), "value"))
|
||||||
|
.ws().append("=").ws().append("value;").softNewLine();
|
||||||
|
|
||||||
|
writer.appendIf().append(context.getParameterName(2)).ws().append("!==").ws().append("null")
|
||||||
|
.ws().append("&&").ws().append("supported)")
|
||||||
|
.appendBlockStart();
|
||||||
|
writer.append(context.getParameterName(2)).append(".")
|
||||||
|
.appendField(new FieldReference(ReferenceQueue.class.getName(), "registry"))
|
||||||
|
.append(".").append("register(").append(context.getParameterName(1))
|
||||||
|
.append(",").ws().append("value);").softNewLine();
|
||||||
|
writer.appendBlockEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateGet(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append("var value").ws().append("=").ws().append(context.getParameterName(0)).append(".")
|
||||||
|
.appendField(new FieldReference(WeakReference.class.getName(), "value"))
|
||||||
|
.append(";").softNewLine();
|
||||||
|
|
||||||
|
writer.appendIf();
|
||||||
|
isSupported(writer).append(")").appendBlockStart();
|
||||||
|
writer.appendIf().append("value").ws().append("===").ws().append("null)")
|
||||||
|
.ws().append("return null;").softNewLine();
|
||||||
|
writer.append("var result").ws().append("=").ws().append("value.deref();").softNewLine();
|
||||||
|
writer.append("return typeof result").ws().append("!==").ws().append("'undefined'")
|
||||||
|
.ws().append("?").ws().append("result").ws().append(":").ws().append("null;").softNewLine();
|
||||||
|
writer.appendElse();
|
||||||
|
writer.append("return value;").softNewLine();
|
||||||
|
writer.appendBlockEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateClear(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append(context.getParameterName(0)).append(".")
|
||||||
|
.appendField(new FieldReference(WeakReference.class.getName(), "value")).ws();
|
||||||
|
writer.append("=").ws().append("null;").softNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SourceWriter isSupported(SourceWriter writer) throws IOException {
|
||||||
|
return writer.append("typeof ").append("$rt_globals.WeakRef").ws().append("!==").ws()
|
||||||
|
.append("'undefined'");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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.backend.javascript.intrinsics.ref;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
import org.teavm.model.ClassHolderTransformerContext;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
|
||||||
|
public class WeakReferenceTransformer implements ClassHolderTransformer {
|
||||||
|
@Override
|
||||||
|
public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
|
||||||
|
if (!cls.getName().equals(WeakReference.class.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (var method : cls.getMethods()) {
|
||||||
|
switch (method.getName()) {
|
||||||
|
case "<init>":
|
||||||
|
if (method.parameterCount() == 2) {
|
||||||
|
method.setProgram(null);
|
||||||
|
method.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "get":
|
||||||
|
case "clear":
|
||||||
|
method.setProgram(null);
|
||||||
|
method.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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.backend.javascript.runtime.ref;
|
||||||
|
|
||||||
|
public final class RuntimeWeakRef {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 konsoletyper.
|
||||||
|
*
|
||||||
|
* 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.ref;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.teavm.junit.SkipJVM;
|
||||||
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
import org.teavm.junit.WholeClassCompilation;
|
||||||
|
|
||||||
|
@RunWith(TeaVMTestRunner.class)
|
||||||
|
@WholeClassCompilation
|
||||||
|
@SkipJVM
|
||||||
|
public class WeakReferenceTest {
|
||||||
|
private Node lastNode;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void deref() {
|
||||||
|
var ref = createAndTestRef(null);
|
||||||
|
|
||||||
|
for (var i = 0; i < 100; ++i) {
|
||||||
|
lastNode = createNodes(18);
|
||||||
|
if (ref.get() == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertNull(ref.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void refQueue() {
|
||||||
|
var queue = new ReferenceQueue<>();
|
||||||
|
var ref = createAndTestRef(queue);
|
||||||
|
var hasValue = false;
|
||||||
|
for (var i = 0; i < 100; ++i) {
|
||||||
|
lastNode = createNodes(18);
|
||||||
|
var polledRef = queue.poll();
|
||||||
|
if (polledRef != null) {
|
||||||
|
hasValue = true;
|
||||||
|
assertNull(ref.get());
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
assertNotNull(ref.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(hasValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WeakReference<Object> createAndTestRef(ReferenceQueue<Object> queue) {
|
||||||
|
var obj = new byte[4 * 1024 * 1024];
|
||||||
|
var ref = new WeakReference<Object>(obj, queue);
|
||||||
|
assertSame(obj, ref.get());
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clear() {
|
||||||
|
var obj = new Object();
|
||||||
|
var ref = new WeakReference<>(obj);
|
||||||
|
assertSame(obj, ref.get());
|
||||||
|
|
||||||
|
ref.clear();
|
||||||
|
assertNull(ref.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node createNodes(int depth) {
|
||||||
|
if (depth == 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new Node(createNodes(depth - 1), createNodes(depth - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Node {
|
||||||
|
Node left;
|
||||||
|
Node right;
|
||||||
|
byte[] data = new byte[64];
|
||||||
|
|
||||||
|
Node(Node left, Node right) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user