mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: support imported functions in disassembler
This commit is contained in:
parent
0057bbd00d
commit
a5212fb9ca
|
@ -27,7 +27,6 @@ import org.teavm.backend.wasm.parser.CodeSectionParser;
|
||||||
import org.teavm.backend.wasm.parser.FunctionSectionListener;
|
import org.teavm.backend.wasm.parser.FunctionSectionListener;
|
||||||
import org.teavm.backend.wasm.parser.FunctionSectionParser;
|
import org.teavm.backend.wasm.parser.FunctionSectionParser;
|
||||||
import org.teavm.backend.wasm.parser.GlobalSectionParser;
|
import org.teavm.backend.wasm.parser.GlobalSectionParser;
|
||||||
import org.teavm.backend.wasm.parser.ImportSectionListener;
|
|
||||||
import org.teavm.backend.wasm.parser.ImportSectionParser;
|
import org.teavm.backend.wasm.parser.ImportSectionParser;
|
||||||
import org.teavm.backend.wasm.parser.ModuleParser;
|
import org.teavm.backend.wasm.parser.ModuleParser;
|
||||||
import org.teavm.backend.wasm.parser.NameSectionListener;
|
import org.teavm.backend.wasm.parser.NameSectionListener;
|
||||||
|
@ -41,6 +40,7 @@ public final class Disassembler {
|
||||||
private DisassemblyWriter writer;
|
private DisassemblyWriter writer;
|
||||||
private WasmHollowFunctionType[] functionTypes;
|
private WasmHollowFunctionType[] functionTypes;
|
||||||
private int[] functionTypeRefs;
|
private int[] functionTypeRefs;
|
||||||
|
private int importFunctionCount;
|
||||||
|
|
||||||
public Disassembler(DisassemblyWriter writer) {
|
public Disassembler(DisassemblyWriter writer) {
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
|
@ -91,17 +91,6 @@ public final class Disassembler {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportListenerImpl importListener = new ImportListenerImpl();
|
|
||||||
|
|
||||||
static class ImportListenerImpl implements ImportSectionListener {
|
|
||||||
int count;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void function(int typeIndex) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Consumer<byte[]> getSectionConsumer(int code, int pos, NameProvider nameProvider) {
|
public Consumer<byte[]> getSectionConsumer(int code, int pos, NameProvider nameProvider) {
|
||||||
if (code == 1) {
|
if (code == 1) {
|
||||||
return bytes -> {
|
return bytes -> {
|
||||||
|
@ -115,13 +104,15 @@ public final class Disassembler {
|
||||||
};
|
};
|
||||||
} else if (code == 2) {
|
} else if (code == 2) {
|
||||||
return bytes -> {
|
return bytes -> {
|
||||||
|
var importListener = new DisassemblyImportSectionListener(writer, nameProvider, functionTypes);
|
||||||
var parser = new ImportSectionParser(importListener);
|
var parser = new ImportSectionParser(importListener);
|
||||||
parser.parse(AddressListener.EMPTY, bytes);
|
parser.parse(AddressListener.EMPTY, bytes);
|
||||||
|
importFunctionCount = importListener.functionCount();
|
||||||
};
|
};
|
||||||
} else if (code == 3) {
|
} else if (code == 3) {
|
||||||
return bytes -> {
|
return bytes -> {
|
||||||
var signatures = new IntArrayList();
|
var signatures = new IntArrayList();
|
||||||
for (var i = 0; i < importListener.count; ++i) {
|
for (var i = 0; i < importFunctionCount; ++i) {
|
||||||
signatures.add(0);
|
signatures.add(0);
|
||||||
}
|
}
|
||||||
var parser = new FunctionSectionParser(new FunctionSectionListener() {
|
var parser = new FunctionSectionParser(new FunctionSectionListener() {
|
||||||
|
@ -150,7 +141,7 @@ public final class Disassembler {
|
||||||
writer.setAddressOffset(pos);
|
writer.setAddressOffset(pos);
|
||||||
writer.write("(; code section size: " + bytes.length + " ;)").eol();
|
writer.write("(; code section size: " + bytes.length + " ;)").eol();
|
||||||
var sectionParser = new CodeSectionParser(disassembler);
|
var sectionParser = new CodeSectionParser(disassembler);
|
||||||
sectionParser.setFunctionIndexOffset(importListener.count);
|
sectionParser.setFunctionIndexOffset(importFunctionCount);
|
||||||
sectionParser.parse(writer.addressListener, bytes);
|
sectionParser.parse(writer.addressListener, bytes);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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.disasm;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.parser.ImportSectionListener;
|
||||||
|
import org.teavm.backend.wasm.parser.WasmHollowFunctionType;
|
||||||
|
|
||||||
|
public class DisassemblyImportSectionListener extends BaseDisassemblyListener implements ImportSectionListener {
|
||||||
|
private WasmHollowFunctionType[] functionTypes;
|
||||||
|
private String currentModule;
|
||||||
|
private String currentName;
|
||||||
|
private int functionIndex;
|
||||||
|
|
||||||
|
public DisassemblyImportSectionListener(DisassemblyWriter writer, NameProvider nameProvider,
|
||||||
|
WasmHollowFunctionType[] functionTypes) {
|
||||||
|
super(writer, nameProvider);
|
||||||
|
this.functionTypes = functionTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int functionCount() {
|
||||||
|
return functionIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startEntry(String module, String name) {
|
||||||
|
currentModule = module;
|
||||||
|
currentName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void function(int typeIndex) {
|
||||||
|
writer.address().write("(import \"").write(currentModule).write("\" \"")
|
||||||
|
.write(currentName).write("\" ");
|
||||||
|
writer.write("(func ");
|
||||||
|
writer.startLinkTarget("f" + functionIndex).write("(; " + functionIndex + " ;)");
|
||||||
|
var name = nameProvider.function(functionIndex);
|
||||||
|
if (name != null) {
|
||||||
|
writer.write(" $").write(name);
|
||||||
|
}
|
||||||
|
writer.endLinkTarget();
|
||||||
|
|
||||||
|
writer.write(" (type ");
|
||||||
|
writeTypeRef(typeIndex);
|
||||||
|
writer.write(")");
|
||||||
|
writer.indent().eol();
|
||||||
|
|
||||||
|
var type = typeIndex < functionTypes.length ? functionTypes[typeIndex] : null;
|
||||||
|
if (type != null) {
|
||||||
|
for (var i = 0; i < type.parameterTypes.length; ++i) {
|
||||||
|
writer.write("(param ");
|
||||||
|
writer.startLinkTarget("l" + functionIndex + "." + i).write(" (; " + i + " ;)");
|
||||||
|
var paramName = nameProvider.local(functionIndex, i);
|
||||||
|
if (paramName != null) {
|
||||||
|
writer.write(" $").write(paramName);
|
||||||
|
}
|
||||||
|
writer.endLinkTarget();
|
||||||
|
writer.write(" ");
|
||||||
|
writeType(type.parameterTypes[i]);
|
||||||
|
writer.write(")").eol();
|
||||||
|
}
|
||||||
|
for (var i = 0; i < type.returnTypes.length; ++i) {
|
||||||
|
writer.write("(result ");
|
||||||
|
writeType(type.returnTypes[i]);
|
||||||
|
writer.write(")").eol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.outdent().write("))").eol();
|
||||||
|
|
||||||
|
functionIndex++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,6 +112,8 @@ public abstract class DisassemblyWriter {
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final AddressListener addressListener = new AddressListener() {
|
public final AddressListener addressListener = new AddressListener() {
|
||||||
@Override
|
@Override
|
||||||
public void address(int address) {
|
public void address(int address) {
|
||||||
|
|
|
@ -462,7 +462,7 @@ public class WasmBinaryRenderer {
|
||||||
|
|
||||||
WasmBinaryWriter functionsSubsection = new WasmBinaryWriter();
|
WasmBinaryWriter functionsSubsection = new WasmBinaryWriter();
|
||||||
var functions = module.functions.stream()
|
var functions = module.functions.stream()
|
||||||
.filter(f -> f.getName() != null && f.getImportName() == null)
|
.filter(f -> f.getName() != null)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
functionsSubsection.writeLEB(functions.size());
|
functionsSubsection.writeLEB(functions.size());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user