mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
next step in handling virtual methods
This commit is contained in:
parent
45d1731126
commit
983d78de54
@ -19,6 +19,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -199,6 +200,18 @@ public class FunctionManager {
|
|||||||
return newMethod != null ? newMethod : method;
|
return newMethod != null ? newMethod : method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all function names for the class.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* the className
|
||||||
|
* @return a stream with the names
|
||||||
|
*/
|
||||||
|
Stream<FunctionName> getNamesOfClass( String className ) {
|
||||||
|
return states.keySet().stream().filter( ( name ) -> name.className.equals( className ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State of a function/method
|
* State of a function/method
|
||||||
*/
|
*/
|
||||||
|
@ -576,6 +576,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
addStructInstruction( StructOperator.SET, ref.getClassName(), new NamedStorageType( ref, getTypeManager() ), codePos, lineNumber );
|
addStructInstruction( StructOperator.SET, ref.getClassName(), new NamedStorageType( ref, getTypeManager() ), codePos, lineNumber );
|
||||||
break;
|
break;
|
||||||
case 182: // invokevirtual
|
case 182: // invokevirtual
|
||||||
|
idx = byteCode.readUnsignedShort();
|
||||||
|
ref = (ConstantRef)constantPool.get( idx );
|
||||||
|
addCallVirtualInstruction( new FunctionName( ref ), codePos, lineNumber );
|
||||||
|
break;
|
||||||
case 183: // invokespecial, invoke a constructor
|
case 183: // invokespecial, invoke a constructor
|
||||||
case 184: // invokestatic
|
case 184: // invokestatic
|
||||||
idx = byteCode.readUnsignedShort();
|
idx = byteCode.readUnsignedShort();
|
||||||
|
@ -23,6 +23,7 @@ import java.net.URLClassLoader;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -213,6 +214,7 @@ public class ModuleGenerator {
|
|||||||
for( WasmInstruction instruction : instructions ) {
|
for( WasmInstruction instruction : instructions ) {
|
||||||
switch( instruction.getType() ) {
|
switch( instruction.getType() ) {
|
||||||
case Call:
|
case Call:
|
||||||
|
case CallIndirect:
|
||||||
((WasmCallInstruction)instruction).markAsNeeded( functions );
|
((WasmCallInstruction)instruction).markAsNeeded( functions );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -314,13 +316,23 @@ public class ModuleGenerator {
|
|||||||
listStructFields( superClassName, list );
|
listStructFields( superClassName, list );
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldInfo[] fields = classFile.getFields();
|
for( FieldInfo field : classFile.getFields() ) {
|
||||||
for( FieldInfo field : fields ) {
|
|
||||||
if( field.isStatic() ) {
|
if( field.isStatic() ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list.add( new NamedStorageType( className, field, types ) );
|
list.add( new NamedStorageType( className, field, types ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashMap<String,Boolean> virtualFunctions = new HashMap<>();
|
||||||
|
functions.getNamesOfClass( className ).forEach( (name) -> {
|
||||||
|
String methodName = name.methodName;
|
||||||
|
Boolean virtual = virtualFunctions.get( methodName );
|
||||||
|
if( virtual == null ) {
|
||||||
|
virtualFunctions.put( methodName, Boolean.FALSE );
|
||||||
|
} else {
|
||||||
|
virtualFunctions.put( methodName, Boolean.TRUE );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -491,6 +503,7 @@ public class ModuleGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Call:
|
case Call:
|
||||||
|
case CallIndirect:
|
||||||
((WasmCallInstruction)instruction).markAsNeeded( functions );
|
((WasmCallInstruction)instruction).markAsNeeded( functions );
|
||||||
break;
|
break;
|
||||||
case Struct:
|
case Struct:
|
||||||
|
@ -17,25 +17,16 @@
|
|||||||
package de.inetsoftware.jwebassembly.module;
|
package de.inetsoftware.jwebassembly.module;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WasmInstruction for a function call.
|
* WasmInstruction for a function call.
|
||||||
*
|
*
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class WasmCallIndirectInstruction extends WasmInstruction {
|
class WasmCallIndirectInstruction extends WasmCallInstruction {
|
||||||
|
|
||||||
private AnyType valueType;
|
|
||||||
|
|
||||||
private final FunctionName name;
|
|
||||||
|
|
||||||
private int paramCount = -1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of a function call instruction
|
* Create an instance of a function call instruction
|
||||||
@ -48,8 +39,7 @@ class WasmCallIndirectInstruction extends WasmInstruction {
|
|||||||
* the line number in the Java source code
|
* the line number in the Java source code
|
||||||
*/
|
*/
|
||||||
WasmCallIndirectInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
|
WasmCallIndirectInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
|
||||||
super( javaCodePos, lineNumber );
|
super( name, javaCodePos, lineNumber );
|
||||||
this.name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,29 +50,16 @@ class WasmCallIndirectInstruction extends WasmInstruction {
|
|||||||
return Type.CallIndirect;
|
return Type.CallIndirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the function name that should be called
|
|
||||||
*
|
|
||||||
* @return the name
|
|
||||||
*/
|
|
||||||
@Nonnull
|
|
||||||
FunctionName getFunctionName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
||||||
writer.writeFunctionCallIndirect( name );
|
if( true ) { // TODO
|
||||||
}
|
super.writeTo( writer );
|
||||||
|
} else {
|
||||||
/**
|
writer.writeFunctionCallIndirect( getFunctionName() );
|
||||||
* {@inheritDoc}
|
}
|
||||||
*/
|
|
||||||
AnyType getPushValueType() {
|
|
||||||
countParams();
|
|
||||||
return valueType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,26 +67,6 @@ class WasmCallIndirectInstruction extends WasmInstruction {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
int getPopCount() {
|
int getPopCount() {
|
||||||
countParams();
|
return super.getPopCount() + 1; // this -> +1
|
||||||
return paramCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count the parameters in the signature
|
|
||||||
*/
|
|
||||||
private void countParams() {
|
|
||||||
if( paramCount >= 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Iterator<AnyType> parser = name.getSignature();
|
|
||||||
paramCount = 1;
|
|
||||||
while( parser.next() != null ) {
|
|
||||||
paramCount++;
|
|
||||||
}
|
|
||||||
valueType = parser.next();
|
|
||||||
while( parser.hasNext() ) {
|
|
||||||
valueType = parser.next();
|
|
||||||
paramCount--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,16 @@ class WasmCallInstruction extends WasmInstruction {
|
|||||||
return Type.Call;
|
return Type.Call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the function name that should be called
|
||||||
|
*
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
FunctionName getFunctionName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the function as needed in the functions manager and replace the function name with a possible super name.
|
* Mark the function as needed in the functions manager and replace the function name with a possible super name.
|
||||||
*
|
*
|
||||||
|
@ -273,6 +273,20 @@ public abstract class WasmCodeBuilder {
|
|||||||
instructions.add( new WasmCallInstruction( name, javaCodePos, lineNumber ) );
|
instructions.add( new WasmCallInstruction( name, javaCodePos, lineNumber ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a virtual/method function call.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the function name that should be called
|
||||||
|
* @param javaCodePos
|
||||||
|
* the code position/offset in the Java method
|
||||||
|
* @param lineNumber
|
||||||
|
* the line number in the Java source code
|
||||||
|
*/
|
||||||
|
protected void addCallVirtualInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
|
||||||
|
instructions.add( new WasmCallIndirectInstruction( name, javaCodePos, lineNumber ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a block operation.
|
* Add a block operation.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user