diff --git a/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoadWasmRuntime.java b/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoadWasmRuntime.java new file mode 100644 index 000000000..fa2adbd3b --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoadWasmRuntime.java @@ -0,0 +1,54 @@ +/* + * 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.impl; + +import org.teavm.backend.wasm.WasmRuntime; +import org.teavm.interop.Address; +import org.teavm.interop.Structure; +import org.teavm.runtime.Allocator; +import org.teavm.runtime.GC; +import org.teavm.runtime.RuntimeArray; +import org.teavm.runtime.RuntimeClass; +import org.teavm.runtime.RuntimeObject; + +final class ServiceLoadWasmRuntime { + private ServiceLoadWasmRuntime() { + } + + @SuppressWarnings("unused") + static RuntimeObject createServices(Address table, RuntimeClass cls) { + var entry = WasmRuntime.lookupResource(table, cls.toAddress()); + if (entry == null) { + return null; + } + entry = entry.add(Address.sizeOf()).getAddress(); + var size = entry.getInt(); + entry = entry.add(4); + RuntimeArray result = Allocator.allocateArray(cls, size).toStructure(); + var resultData = WasmRuntime.align(result.toAddress().add(Structure.sizeOf(RuntimeArray.class)), + Address.sizeOf()); + for (var i = 0; i < size; ++i) { + RuntimeObject obj = Allocator.allocate(entry.getAddress().toStructure()).toStructure(); + entry = entry.add(Address.sizeOf()); + WasmRuntime.callFunctionFromTable(entry.getInt(), obj); + entry = entry.add(4); + resultData.putAddress(obj.toAddress()); + resultData = resultData.add(Address.sizeOf()); + GC.writeBarrier(result); + } + return result; + } +} diff --git a/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderWasmSupport.java b/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderWasmSupport.java index 445902175..0ee7bc70f 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderWasmSupport.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderWasmSupport.java @@ -17,7 +17,6 @@ package org.teavm.classlib.impl; import java.util.ServiceLoader; import org.teavm.ast.InvocationExpr; -import org.teavm.backend.wasm.WasmRuntime; import org.teavm.backend.wasm.binary.DataPrimitives; import org.teavm.backend.wasm.binary.DataStructure; import org.teavm.backend.wasm.intrinsics.WasmIntrinsic; @@ -29,12 +28,8 @@ import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.backend.wasm.model.expression.WasmInt32Constant; import org.teavm.dependency.DependencyAnalyzer; import org.teavm.interop.Address; -import org.teavm.interop.Structure; import org.teavm.model.MethodReference; import org.teavm.model.ValueType; -import org.teavm.runtime.Allocator; -import org.teavm.runtime.GC; -import org.teavm.runtime.RuntimeArray; import org.teavm.runtime.RuntimeClass; import org.teavm.runtime.RuntimeObject; @@ -45,7 +40,7 @@ public class ServiceLoaderWasmSupport implements WasmIntrinsicFactory { DataPrimitives.INT ); private static final MethodReference CREATE_SERVICES_METHOD = new MethodReference( - ServiceLoaderWasmSupport.class, "createServices", Address.class, Address.class); + ServiceLoadWasmRuntime.class, "createServices", Address.class, RuntimeClass.class, RuntimeObject.class); @Override public WasmIntrinsic create(WasmIntrinsicFactoryContext context) { @@ -54,7 +49,7 @@ public class ServiceLoaderWasmSupport implements WasmIntrinsicFactory { @Override public void contributeDependencies(DependencyAnalyzer analyzer) { - analyzer.linkMethod(CREATE_SERVICES_METHOD); + analyzer.linkMethod(CREATE_SERVICES_METHOD).use(); } private static class ServiceLoaderIntrinsic implements WasmIntrinsic { @@ -111,26 +106,4 @@ public class ServiceLoaderWasmSupport implements WasmIntrinsicFactory { } } - static RuntimeObject createServices(Address table, RuntimeClass cls) { - var entry = WasmRuntime.lookupResource(table, cls.toAddress()); - if (entry == null) { - return null; - } - entry = entry.add(Address.sizeOf()).getAddress(); - var size = entry.getInt(); - entry = entry.add(4); - RuntimeArray result = Allocator.allocateArray(cls, size).toStructure(); - var resultData = WasmRuntime.align(result.toAddress().add(Structure.sizeOf(RuntimeArray.class)), - Address.sizeOf()); - for (var i = 0; i < size; ++i) { - RuntimeObject obj = Allocator.allocate(entry.getAddress().toStructure()).toStructure(); - entry = entry.add(Address.sizeOf()); - WasmRuntime.callFunctionFromTable(entry.getInt(), obj); - entry = entry.add(4); - resultData.putAddress(obj.toAddress()); - resultData = resultData.add(Address.sizeOf()); - GC.writeBarrier(result); - } - return result; - } } diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/WasmRuntimeIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/WasmRuntimeIntrinsic.java index 0acc58f10..fc31737e0 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/WasmRuntimeIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/WasmRuntimeIntrinsic.java @@ -73,6 +73,7 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic { invocation, manager); case "callFunctionFromTable": { var call = new WasmIndirectCall(manager.generate(invocation.getArguments().get(0))); + call.getParameterTypes().add(WasmType.INT32); call.getArguments().add(manager.generate(invocation.getArguments().get(1))); return call; }