From 530b6a5da5f0a2b16e5bef8c2b5022642392870e Mon Sep 17 00:00:00 2001 From: lax1dude Date: Mon, 2 Dec 2024 19:47:22 -0800 Subject: [PATCH] Add class transformers to convert functions to native --- .../org/teavm/backend/wasm/WasmTarget.java | 2 + .../BaseClassesTransformation.java | 41 +++++++++++++++++++ .../gc/BaseClassesTransformation.java | 11 +++++ 3 files changed, 54 insertions(+) create mode 100644 core/src/main/java/org/teavm/backend/wasm/transformation/BaseClassesTransformation.java diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java index 728287f18..c94060dbd 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java @@ -115,6 +115,7 @@ import org.teavm.backend.wasm.render.WasmBinaryWriter; import org.teavm.backend.wasm.render.WasmCRenderer; import org.teavm.backend.wasm.render.WasmRenderer; import org.teavm.backend.wasm.runtime.WasmSupport; +import org.teavm.backend.wasm.transformation.BaseClassesTransformation; import org.teavm.backend.wasm.transformation.IndirectCallTraceTransformation; import org.teavm.backend.wasm.transformation.MemoryAccessTraceTransformation; import org.teavm.backend.wasm.transformation.WasiFileSystemProviderTransformer; @@ -241,6 +242,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost { public List getTransformers() { List transformers = new ArrayList<>(); transformers.add(new ClassPatch()); + transformers.add(new BaseClassesTransformation()); transformers.add(new WasmDependencyListener()); if (runtimeType == WasmRuntimeType.WASI) { transformers.add(new WasiSupportClassTransformer()); diff --git a/core/src/main/java/org/teavm/backend/wasm/transformation/BaseClassesTransformation.java b/core/src/main/java/org/teavm/backend/wasm/transformation/BaseClassesTransformation.java new file mode 100644 index 000000000..abcfb4ae4 --- /dev/null +++ b/core/src/main/java/org/teavm/backend/wasm/transformation/BaseClassesTransformation.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 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.wasm.transformation; + +import org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; +import org.teavm.model.ClassHolderTransformerContext; +import org.teavm.model.ElementModifier; + +public class BaseClassesTransformation implements ClassHolderTransformer { + + @Override + public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) { + if (cls.getName().equals("java.lang.Integer") || cls.getName().equals("java.lang.Long")) { + for (var method : cls.getMethods()) { + switch (method.getName()) { + case "numberOfLeadingZeros": + case "numberOfTrailingZeros": + case "bitCount": + method.setProgram(null); + method.getModifiers().add(ElementModifier.NATIVE); + break; + } + } + } + } + +} diff --git a/core/src/main/java/org/teavm/backend/wasm/transformation/gc/BaseClassesTransformation.java b/core/src/main/java/org/teavm/backend/wasm/transformation/gc/BaseClassesTransformation.java index 6b24229c5..ce0ea18ef 100644 --- a/core/src/main/java/org/teavm/backend/wasm/transformation/gc/BaseClassesTransformation.java +++ b/core/src/main/java/org/teavm/backend/wasm/transformation/gc/BaseClassesTransformation.java @@ -121,6 +121,17 @@ public class BaseClassesTransformation implements ClassHolderTransformer { var clear = cls.getMethod(new MethodDescriptor("clear", void.class)); clear.getModifiers().add(ElementModifier.NATIVE); clear.setProgram(null); + } else if (cls.getName().equals("java.lang.Integer") || cls.getName().equals("java.lang.Long")) { + for (var method : cls.getMethods()) { + switch (method.getName()) { + case "numberOfLeadingZeros": + case "numberOfTrailingZeros": + case "bitCount": + method.setProgram(null); + method.getModifiers().add(ElementModifier.NATIVE); + break; + } + } } }