next step in handling virtual methods

This commit is contained in:
Volker Berlin 2019-05-14 21:47:49 +02:00
parent 45d1731126
commit 983d78de54
6 changed files with 65 additions and 54 deletions

View File

@ -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
*/ */

View File

@ -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();

View File

@ -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:

View File

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

View File

@ -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.
* *

View File

@ -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.
* *