wasm: fix ServiceLoader

This commit is contained in:
Alexey Andreev 2023-10-02 14:05:25 +02:00
parent eab9254bfe
commit 2c00df288f
3 changed files with 57 additions and 29 deletions

View File

@ -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;
}
}

View File

@ -17,7 +17,6 @@ package org.teavm.classlib.impl;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import org.teavm.ast.InvocationExpr; import org.teavm.ast.InvocationExpr;
import org.teavm.backend.wasm.WasmRuntime;
import org.teavm.backend.wasm.binary.DataPrimitives; import org.teavm.backend.wasm.binary.DataPrimitives;
import org.teavm.backend.wasm.binary.DataStructure; import org.teavm.backend.wasm.binary.DataStructure;
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic; 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.backend.wasm.model.expression.WasmInt32Constant;
import org.teavm.dependency.DependencyAnalyzer; import org.teavm.dependency.DependencyAnalyzer;
import org.teavm.interop.Address; import org.teavm.interop.Address;
import org.teavm.interop.Structure;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ValueType; 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.RuntimeClass;
import org.teavm.runtime.RuntimeObject; import org.teavm.runtime.RuntimeObject;
@ -45,7 +40,7 @@ public class ServiceLoaderWasmSupport implements WasmIntrinsicFactory {
DataPrimitives.INT DataPrimitives.INT
); );
private static final MethodReference CREATE_SERVICES_METHOD = new MethodReference( 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 @Override
public WasmIntrinsic create(WasmIntrinsicFactoryContext context) { public WasmIntrinsic create(WasmIntrinsicFactoryContext context) {
@ -54,7 +49,7 @@ public class ServiceLoaderWasmSupport implements WasmIntrinsicFactory {
@Override @Override
public void contributeDependencies(DependencyAnalyzer analyzer) { public void contributeDependencies(DependencyAnalyzer analyzer) {
analyzer.linkMethod(CREATE_SERVICES_METHOD); analyzer.linkMethod(CREATE_SERVICES_METHOD).use();
} }
private static class ServiceLoaderIntrinsic implements WasmIntrinsic { 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;
}
} }

View File

@ -73,6 +73,7 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
invocation, manager); invocation, manager);
case "callFunctionFromTable": { case "callFunctionFromTable": {
var call = new WasmIndirectCall(manager.generate(invocation.getArguments().get(0))); var call = new WasmIndirectCall(manager.generate(invocation.getArguments().get(0)));
call.getParameterTypes().add(WasmType.INT32);
call.getArguments().add(manager.generate(invocation.getArguments().get(1))); call.getArguments().add(manager.generate(invocation.getArguments().get(1)));
return call; return call;
} }