mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Wasm: fix bugs
This commit is contained in:
parent
871e9a0113
commit
28c0cc6ef2
|
@ -518,7 +518,8 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
for (String className : classes.getClassNames()) {
|
||||
ClassHolder cls = classes.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (context.getIntrinsic(method.getReference()) != null) {
|
||||
if (method.hasModifier(ElementModifier.ABSTRACT)
|
||||
|| context.getIntrinsic(method.getReference()) != null) {
|
||||
continue;
|
||||
}
|
||||
module.add(generator.generateDefinition(method.getReference()));
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
package org.teavm.backend.wasm.generate;
|
||||
|
||||
import com.carrotsearch.hppc.ObjectIntHashMap;
|
||||
import com.carrotsearch.hppc.ObjectIntMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.teavm.backend.wasm.binary.BinaryWriter;
|
||||
import org.teavm.backend.wasm.binary.DataPrimitives;
|
||||
import org.teavm.backend.wasm.binary.DataStructure;
|
||||
|
@ -29,28 +30,31 @@ import org.teavm.model.lowlevel.CallSiteLocation;
|
|||
import org.teavm.model.lowlevel.ExceptionHandlerDescriptor;
|
||||
|
||||
public class CallSiteBinaryGenerator {
|
||||
private static final int CALL_SITE_HANDLER_COUNT = 0;
|
||||
private static final int CALL_SITE_FIRST_HANDLER = 1;
|
||||
private static final int CALL_SITE_LOCATION = 2;
|
||||
private static final int CALL_SITE_FIRST_HANDLER = 0;
|
||||
private static final int CALL_SITE_LOCATION = 1;
|
||||
private static final int EXCEPTION_HANDLER_ID = 0;
|
||||
private static final int EXCEPTION_HANDLER_CLASS = 1;
|
||||
private static final int LOCATION_FILE = 0;
|
||||
private static final int LOCATION_CLASS = 1;
|
||||
private static final int LOCATION_METHOD = 2;
|
||||
private static final int LOCATION_LINE_NUMBER = 3;
|
||||
private static final int EXCEPTION_HANDLER_NEXT = 2;
|
||||
private static final int LOCATION_METHOD = 0;
|
||||
private static final int LOCATION_LINE = 1;
|
||||
private static final int METHOD_LOCATION_FILE = 0;
|
||||
private static final int METHOD_LOCATION_CLASS = 1;
|
||||
private static final int METHOD_LOCATION_METHOD = 2;
|
||||
|
||||
private DataStructure callSiteStructure = new DataStructure((byte) 0,
|
||||
DataPrimitives.INT,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS);
|
||||
private DataStructure exceptionHandlerStructure = new DataStructure((byte) 0,
|
||||
DataPrimitives.INT,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS);
|
||||
private DataStructure locationStructure = new DataStructure((byte) 0,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.INT);
|
||||
private DataStructure methodLocationStructure = new DataStructure((byte) 0,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS,
|
||||
DataPrimitives.ADDRESS);
|
||||
|
||||
private BinaryWriter writer;
|
||||
private WasmClassGenerator classGenerator;
|
||||
|
@ -78,12 +82,12 @@ public class CallSiteBinaryGenerator {
|
|||
binaryCallSites.add(binaryCallSite);
|
||||
}
|
||||
|
||||
Map<CallSiteLocation, Integer> locationCache = new HashMap<>();
|
||||
ObjectIntMap<CallSiteLocation> locationCache = new ObjectIntHashMap<>();
|
||||
ObjectIntMap<MethodLocation> methodLocationCache = new ObjectIntHashMap<>();
|
||||
|
||||
for (int callSiteId = 0; callSiteId < callSites.size(); ++callSiteId) {
|
||||
DataValue binaryCallSite = binaryCallSites.get(callSiteId);
|
||||
CallSiteDescriptor callSite = callSites.get(callSiteId);
|
||||
binaryCallSite.setInt(CALL_SITE_HANDLER_COUNT, callSite.getHandlers().size());
|
||||
|
||||
boolean firstHandlerSet = false;
|
||||
List<DataValue> binaryExceptionHandlers = new ArrayList<>();
|
||||
|
@ -98,6 +102,9 @@ public class CallSiteBinaryGenerator {
|
|||
binaryCallSite.setAddress(CALL_SITE_FIRST_HANDLER, address);
|
||||
firstHandlerSet = true;
|
||||
}
|
||||
if (i > 0) {
|
||||
binaryExceptionHandlers.get(i - 1).setAddress(EXCEPTION_HANDLER_NEXT, address);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < callSite.getHandlers().size(); ++i) {
|
||||
|
@ -110,24 +117,70 @@ public class CallSiteBinaryGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
int locationAddress = locationCache.computeIfAbsent(callSite.getLocation(), location -> {
|
||||
CallSiteLocation location = callSite.getLocation();
|
||||
int locationAddress = locationCache.getOrDefault(location, -1);
|
||||
if (locationAddress < 0) {
|
||||
DataValue binaryLocation = locationStructure.createValue();
|
||||
int address = writer.append(binaryLocation);
|
||||
if (location.getFileName() != null) {
|
||||
binaryLocation.setAddress(LOCATION_FILE, stringPool.getStringPointer(location.getFileName()));
|
||||
locationAddress = writer.append(binaryLocation);
|
||||
locationCache.put(location, locationAddress);
|
||||
MethodLocation methodLocation = new MethodLocation(location.getFileName(), location.getClassName(),
|
||||
location.getMethodName());
|
||||
int methodLocationAddress = methodLocationCache.getOrDefault(methodLocation, -1);
|
||||
if (methodLocationAddress < 0) {
|
||||
DataValue binaryMethodLocation = methodLocationStructure.createValue();
|
||||
methodLocationAddress = writer.append(binaryMethodLocation);
|
||||
methodLocationCache.put(methodLocation, methodLocationAddress);
|
||||
if (location.getFileName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_FILE,
|
||||
stringPool.getStringPointer(location.getFileName()));
|
||||
}
|
||||
if (location.getClassName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_CLASS,
|
||||
stringPool.getStringPointer(location.getClassName()));
|
||||
}
|
||||
if (location.getMethodName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_METHOD,
|
||||
stringPool.getStringPointer(location.getMethodName()));
|
||||
}
|
||||
}
|
||||
if (location.getClassName() != null) {
|
||||
binaryLocation.setAddress(LOCATION_CLASS, stringPool.getStringPointer(location.getClassName()));
|
||||
}
|
||||
if (location.getMethodName() != null) {
|
||||
binaryLocation.setAddress(LOCATION_METHOD, stringPool.getStringPointer(location.getMethodName()));
|
||||
}
|
||||
binaryLocation.setInt(LOCATION_LINE_NUMBER, location.getLineNumber());
|
||||
return address;
|
||||
});
|
||||
|
||||
binaryLocation.setAddress(LOCATION_METHOD, methodLocationAddress);
|
||||
binaryLocation.setInt(LOCATION_LINE, location.getLineNumber());
|
||||
}
|
||||
binaryCallSite.setAddress(CALL_SITE_LOCATION, locationAddress);
|
||||
}
|
||||
|
||||
return firstCallSite;
|
||||
}
|
||||
|
||||
final static class MethodLocation {
|
||||
final String file;
|
||||
final String className;
|
||||
final String methodName;
|
||||
|
||||
MethodLocation(String file, String className, String methodName) {
|
||||
this.file = file;
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof MethodLocation)) {
|
||||
return false;
|
||||
}
|
||||
MethodLocation that = (MethodLocation) o;
|
||||
return Objects.equals(file, that.file)
|
||||
&& Objects.equals(className, that.className)
|
||||
&& Objects.equals(methodName, that.methodName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(file, className, methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ public class WasmClassGenerator {
|
|||
DataPrimitives.INT, /* isInstance function */
|
||||
DataPrimitives.INT, /* init function */
|
||||
DataPrimitives.ADDRESS, /* parent */
|
||||
DataPrimitives.INT, /* interface count */
|
||||
DataPrimitives.ADDRESS, /* interfaces */
|
||||
DataPrimitives.ADDRESS, /* enum values */
|
||||
DataPrimitives.ADDRESS, /* layout */
|
||||
DataPrimitives.ADDRESS /* simple name */);
|
||||
|
@ -92,9 +94,9 @@ public class WasmClassGenerator {
|
|||
private static final int CLASS_IS_INSTANCE = 8;
|
||||
private static final int CLASS_INIT = 9;
|
||||
private static final int CLASS_PARENT = 10;
|
||||
private static final int CLASS_ENUM_VALUES = 11;
|
||||
private static final int CLASS_LAYOUT = 12;
|
||||
private static final int CLASS_SIMPLE_NAME = 13;
|
||||
private static final int CLASS_ENUM_VALUES = 13;
|
||||
private static final int CLASS_LAYOUT = 14;
|
||||
private static final int CLASS_SIMPLE_NAME = 15;
|
||||
|
||||
public WasmClassGenerator(ClassReaderSource processedClassSource, ClassReaderSource classSource,
|
||||
VirtualTableProvider vtableProvider, TagRegistry tagRegistry, BinaryWriter binaryWriter,
|
||||
|
@ -377,13 +379,13 @@ public class WasmClassGenerator {
|
|||
private void fillVirtualTable(VirtualTable vtable, DataValue array) {
|
||||
int index = 0;
|
||||
List<VirtualTable> tables = new ArrayList<>();
|
||||
while (vtable != null) {
|
||||
tables.add(vtable);
|
||||
vtable = vtable.getParent();
|
||||
VirtualTable vt = vtable;
|
||||
while (vt != null) {
|
||||
tables.add(vt);
|
||||
vt = vt.getParent();
|
||||
}
|
||||
for (int i = tables.size() - 1; i >= 0; --i) {
|
||||
vtable = tables.get(i);
|
||||
for (MethodDescriptor method : vtable.getMethods()) {
|
||||
for (MethodDescriptor method : tables.get(i).getMethods()) {
|
||||
int methodIndex = -1;
|
||||
if (method != null) {
|
||||
VirtualTableEntry entry = vtable.getEntry(method);
|
||||
|
|
|
@ -110,10 +110,11 @@ import org.teavm.backend.wasm.render.WasmTypeInference;
|
|||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.TextLocation;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.classes.VirtualTableEntry;
|
||||
import org.teavm.model.classes.VirtualTable;
|
||||
import org.teavm.runtime.Allocator;
|
||||
import org.teavm.runtime.RuntimeArray;
|
||||
import org.teavm.runtime.RuntimeClass;
|
||||
|
@ -909,10 +910,12 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
}
|
||||
|
||||
if (expr.getType() == InvocationType.STATIC || expr.getType() == InvocationType.SPECIAL) {
|
||||
String methodName = context.names.forMethod(expr.getMethod());
|
||||
MethodReader method = context.getClassSource().resolve(expr.getMethod());
|
||||
MethodReference reference = method != null ? method.getReference() : expr.getMethod();
|
||||
String methodName = context.names.forMethod(reference);
|
||||
|
||||
WasmCall call = new WasmCall(methodName);
|
||||
if (context.getImportedMethod(expr.getMethod()) != null) {
|
||||
if (context.getImportedMethod(reference) != null) {
|
||||
call.setImported(true);
|
||||
}
|
||||
for (Expr argument : expr.getArguments()) {
|
||||
|
@ -942,23 +945,31 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
|
||||
result = block;
|
||||
} else {
|
||||
MethodReference reference = expr.getMethod();
|
||||
accept(expr.getArguments().get(0));
|
||||
WasmExpression instance = result;
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
block.setType(WasmGeneratorUtil.mapType(expr.getMethod().getReturnType()));
|
||||
block.setType(WasmGeneratorUtil.mapType(reference.getReturnType()));
|
||||
|
||||
WasmLocal instanceVar = getTemporary(WasmType.INT32);
|
||||
block.getBody().add(new WasmSetLocal(instanceVar, instance));
|
||||
instance = new WasmGetLocal(instanceVar);
|
||||
|
||||
int vtableOffset = classGenerator.getClassSize(RuntimeClass.class.getName());
|
||||
VirtualTableEntry vtableEntry = context.getVirtualTableProvider().lookup(expr.getMethod());
|
||||
if (vtableEntry == null) {
|
||||
VirtualTable vtable = context.getVirtualTableProvider().lookup(reference.getClassName());
|
||||
if (vtable != null) {
|
||||
vtable = vtable.findMethodContainer(reference.getDescriptor());
|
||||
}
|
||||
if (vtable == null) {
|
||||
result = new WasmUnreachable();
|
||||
return;
|
||||
}
|
||||
int vtableIndex = vtable.getMethods().indexOf(reference.getDescriptor());
|
||||
if (vtable.getParent() != null) {
|
||||
vtableIndex += vtable.getParent().size();
|
||||
}
|
||||
WasmExpression methodIndex = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
|
||||
getReferenceToClass(instance), new WasmInt32Constant(vtableEntry.getIndex() * 4 + vtableOffset));
|
||||
getReferenceToClass(instance), new WasmInt32Constant(vtableIndex * 4 + vtableOffset));
|
||||
methodIndex = new WasmLoadInt32(4, methodIndex, WasmInt32Subtype.INT32);
|
||||
|
||||
WasmIndirectCall call = new WasmIndirectCall(methodIndex);
|
||||
|
|
|
@ -333,13 +333,10 @@ public class WasmBinaryRenderer {
|
|||
|
||||
WasmBinaryWriter functionsSubsection = new WasmBinaryWriter();
|
||||
Collection<WasmFunction> functions = module.getFunctions().values();
|
||||
|
||||
functions = functions.stream().filter(f -> f.getImportName() != null).collect(Collectors.toList());
|
||||
functionsSubsection.writeLEB(functions.size());
|
||||
|
||||
for (WasmFunction function : functions) {
|
||||
if (function.getImportName() != null) {
|
||||
continue;
|
||||
}
|
||||
functionsSubsection.writeLEB(functionIndexes.get(function.getName()));
|
||||
functionsSubsection.writeAsciiString(function.getName());
|
||||
}
|
||||
|
|
|
@ -40,4 +40,13 @@ inline static int32_t reinterpret_float32(double v) {
|
|||
inline static float reinterpret_int32(int32_t v) {
|
||||
reinterpret_union_32.i = v;
|
||||
return reinterpret_union_32.f;
|
||||
}
|
||||
|
||||
static void logOutOfMemory() {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void logString(int32_t v) {
|
||||
}
|
||||
static void logInt(int32_t v) {
|
||||
}
|
|
@ -154,7 +154,6 @@
|
|||
<optimizationLevel>FULL</optimizationLevel>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!--
|
||||
<execution>
|
||||
<id>wasm-client</id>
|
||||
<goals>
|
||||
|
@ -169,7 +168,6 @@
|
|||
<heapSize>8</heapSize>
|
||||
</configuration>
|
||||
</execution>
|
||||
-->
|
||||
<execution>
|
||||
<id>native-client</id>
|
||||
<goals>
|
||||
|
|
Loading…
Reference in New Issue
Block a user