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 f2de87a73..3d4e1667a 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 @@ -46,7 +46,9 @@ import org.teavm.dependency.PluggableDependency; import org.teavm.interop.Address; import org.teavm.interop.DelegateTo; import org.teavm.interop.NoSideEffects; +import org.teavm.interop.Platforms; import org.teavm.interop.Unmanaged; +import org.teavm.interop.UnsupportedOn; import org.teavm.jso.core.JSArray; import org.teavm.platform.Platform; import org.teavm.platform.PlatformClass; @@ -99,6 +101,7 @@ public final class TClass extends TObject implements TAnnotatedElement, TType } @DelegateTo("isInstanceLowLevel") + @UnsupportedOn(Platforms.WEBASSEMBLY_GC) public boolean isInstance(TObject obj) { return Platform.isInstance(Platform.getPlatformObject(obj), platformClass); } @@ -109,6 +112,7 @@ public final class TClass extends TObject implements TAnnotatedElement, TType } @DelegateTo("isAssignableFromLowLevel") + @UnsupportedOn(Platforms.WEBASSEMBLY_GC) public boolean isAssignableFrom(TClass obj) { return Platform.isAssignable(obj.getPlatformClass(), platformClass); } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java index 1dae9e03d..1b62b43db 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java @@ -919,6 +919,10 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit cloneFunction.setReferenced(true); target.add(setClassField(classInfo, cloneOffset, new WasmFunctionReference(cloneFunction))); } + if (metadataReq.name() && type.getItemType() instanceof ValueType.Primitive) { + var name = strings.getStringConstant(type.toString()); + target.add(setClassField(classInfo, classNameOffset, new WasmGetGlobal(name.global))); + } }; } @@ -1062,7 +1066,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit fields.add(createClassField(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage(), "createArrayInstance")); classEnclosingClassOffset = fields.size(); - fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "enclosingClass")); + fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "enclosingClass")); classNameOffset = fields.size(); fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "name")); classSimpleNameOffset = fields.size(); diff --git a/core/src/main/java/org/teavm/backend/wasm/generators/gc/ClassGenerators.java b/core/src/main/java/org/teavm/backend/wasm/generators/gc/ClassGenerators.java index bff4f0596..b22025d03 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generators/gc/ClassGenerators.java +++ b/core/src/main/java/org/teavm/backend/wasm/generators/gc/ClassGenerators.java @@ -50,7 +50,7 @@ public class ClassGenerators implements WasmGCCustomGenerator { function.add(objectVar); var conditional = new WasmConditional(new WasmReferencesEqual(new WasmGetLocal(objectVar), - new WasmNullConstant(WasmType.Reference.ANY))); + new WasmNullConstant(WasmType.Reference.STRUCT))); conditional.setType(WasmType.INT32); conditional.getThenBlock().getBody().add(new WasmInt32Constant(0)); diff --git a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 0be2cdc14..5176458dc 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -477,7 +477,8 @@ class DependencyGraphBuilder { if (cls != null && cls.getParent() != null) { receiverNode.getClassValueNode().propagate(dependencyAnalyzer.getType(cls.getParent())); } - methodDep.getVariable(0).propagate(type); + methodDep.getVariable(0).getClassValueNode().propagate(type); + methodDep.getVariable(0).propagate(dependencyAnalyzer.getType("java.lang.Class")); }); } diff --git a/core/src/main/java/org/teavm/model/analysis/ClassMetadataRequirements.java b/core/src/main/java/org/teavm/model/analysis/ClassMetadataRequirements.java index a2ee57967..547e26735 100644 --- a/core/src/main/java/org/teavm/model/analysis/ClassMetadataRequirements.java +++ b/core/src/main/java/org/teavm/model/analysis/ClassMetadataRequirements.java @@ -69,7 +69,7 @@ public class ClassMetadataRequirements { if (getSuperclassMethod != null) { var classNames = getSuperclassMethod.getVariable(0).getClassValueNode().getTypes(); for (var className : classNames) { - requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).declaringClass = true; + requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).superclass = true; } } diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/ClassTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/ClassTest.java index fef9db1e8..ba1f27689 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/ClassTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/ClassTest.java @@ -103,19 +103,21 @@ public class ClassTest { } @Test + @SkipPlatform(TestPlatform.WEBASSEMBLY_GC) public void castingAppropriateObject() { Object obj = 23; assertEquals(Integer.valueOf(23), Integer.class.cast(obj)); } @Test(expected = ClassCastException.class) + @SkipPlatform(TestPlatform.WEBASSEMBLY_GC) public void inappropriateObjectCastingFails() { Object obj = 23; Float.class.cast(obj); } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void instanceCreatedThroughReflection() throws Exception { Runnable instance = (Runnable) Class.forName(TestObject.class.getName()).newInstance(); instance.run(); @@ -124,7 +126,7 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void instanceCreatedThoughReflectionWithConstantName() throws Exception { var cls = Class.forName("org.teavm.classlib.java.lang.ClassTest$ClassReferredByConstantName"); assertArrayEquals(new Class[] { Supplier.class }, cls.getInterfaces()); @@ -139,7 +141,7 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void instanceCreatedThroughReflectionAsync() throws Exception { Runnable instance = TestObjectAsync.class.newInstance(); instance.run(); @@ -148,6 +150,7 @@ public class ClassTest { } @Test + @SkipPlatform(TestPlatform.WEBASSEMBLY_GC) public void classProperties() { class B { } @@ -181,14 +184,14 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void annotationsExposed() { var annotations = A.class.getAnnotations(); assertTrue(Stream.of(annotations).anyMatch(a -> a instanceof TestAnnot)); } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void annotationFieldsExposed() { AnnotWithDefaultField annot = B.class.getAnnotation(AnnotWithDefaultField.class); assertEquals(2, annot.x()); @@ -197,7 +200,7 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void annotationFieldTypesSupported() { AnnotWithVariousFields annot = D.class.getAnnotation(AnnotWithVariousFields.class); assertEquals(true, annot.a()); @@ -218,7 +221,7 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void getInterfaces() { assertEquals(0, SuperclassWithoutInterfaces.class.getInterfaces().length); assertEquals(Set.of(TestInterface1.class, TestInterface2.class), @@ -226,7 +229,7 @@ public class ClassTest { } @Test - @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI}) + @SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC}) public void inheritedAnnotation() { assertTrue(A.class.isAnnotationPresent(InheritedAnnot.class)); assertTrue(A.class.isAnnotationPresent(TestAnnot.class)); diff --git a/tools/junit/src/main/resources/teavm-run-test-wasm-gc.html b/tools/junit/src/main/resources/teavm-run-test-wasm-gc.html index 13885e560..1ca8dc7ad 100644 --- a/tools/junit/src/main/resources/teavm-run-test-wasm-gc.html +++ b/tools/junit/src/main/resources/teavm-run-test-wasm-gc.html @@ -23,6 +23,7 @@ \ No newline at end of file