mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
use a synthetic function call to calculate the function id of a virtual call.
This commit is contained in:
parent
db002f8d96
commit
02696a6488
@ -40,9 +40,9 @@ import de.inetsoftware.classparser.ClassFile;
|
||||
import de.inetsoftware.jwebassembly.binary.BinaryModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleGenerator;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.WasmOptions;
|
||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||
import de.inetsoftware.jwebassembly.text.TextModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* The main class of the compiler.
|
||||
|
@ -32,6 +32,7 @@ import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.module.WasmOptions;
|
||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||
import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter;
|
||||
import de.inetsoftware.jwebassembly.sourcemap.SourceMapping;
|
||||
@ -44,7 +45,6 @@ import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Module Writer for binary format. http://webassembly.org/docs/binary-encoding/
|
||||
|
@ -25,7 +25,7 @@ import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
public class CodeOptimizer {
|
||||
class CodeOptimizer {
|
||||
|
||||
/**
|
||||
* Optimize the code before writing.
|
||||
|
@ -34,7 +34,7 @@ import de.inetsoftware.jwebassembly.WasmException;
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
public class FunctionManager {
|
||||
class FunctionManager {
|
||||
|
||||
private final Map<FunctionName, FunctionState> states = new LinkedHashMap<>();
|
||||
|
||||
|
@ -46,7 +46,6 @@ import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
import de.inetsoftware.jwebassembly.watparser.WatParser;
|
||||
|
||||
/**
|
||||
|
@ -33,7 +33,6 @@ import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Module Writer base class.
|
||||
|
@ -27,14 +27,13 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import de.inetsoftware.jwebassembly.api.annotation.WasmTextCode;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Handle all the constant strings. The constant strings will be write into the data section.
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
public class StringManager extends LinkedHashMap<String, Integer> {
|
||||
class StringManager extends LinkedHashMap<String, Integer> {
|
||||
|
||||
/**
|
||||
* Signature of method stringConstant.
|
||||
@ -54,7 +53,7 @@ public class StringManager extends LinkedHashMap<String, Integer> {
|
||||
* @param options
|
||||
* compiler properties and shared managers
|
||||
*/
|
||||
public StringManager( WasmOptions options ) {
|
||||
StringManager( WasmOptions options ) {
|
||||
this.functions = options.functions;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import de.inetsoftware.classparser.ClassFile;
|
||||
import de.inetsoftware.classparser.ClassFile.Type;
|
||||
import de.inetsoftware.classparser.ConstantClass;
|
||||
@ -34,7 +36,6 @@ import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ArrayType;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Manage the written and to write types (classes)
|
||||
@ -60,7 +61,7 @@ public class TypeManager {
|
||||
* @param options
|
||||
* compiler properties
|
||||
*/
|
||||
public TypeManager( WasmOptions options ) {
|
||||
TypeManager( WasmOptions options ) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@ -87,7 +88,7 @@ public class TypeManager {
|
||||
* Get the StructType. If needed an instance is created.
|
||||
*
|
||||
* @param name
|
||||
* the type name
|
||||
* the type name like java/lang/Object
|
||||
* @return the struct type
|
||||
*/
|
||||
public StructType valueOf( String name ) {
|
||||
@ -123,6 +124,24 @@ public class TypeManager {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FunctionName for a virtual call and mark it as used. The function has 2 parameters (THIS,
|
||||
* virtualfunctionIndex) and returns the index of the function.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Nonnull
|
||||
WatCodeSyntheticFunctionName getCallVirtualGC() {
|
||||
return new WatCodeSyntheticFunctionName( //
|
||||
"callVirtual", "local.get 0 " // THIS
|
||||
+ "struct.get java/lang/Object .vtable " // vtable is on index 0
|
||||
+ "local.get 1 " // virtualFunctionIndex
|
||||
+ "i32.add " //
|
||||
+ "i32.load offset=0 align=4 " //
|
||||
+ "return " //
|
||||
, valueOf( "java/lang/Object" ), ValueType.i32, null, ValueType.i32 ); //
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to a type.
|
||||
*
|
||||
|
@ -22,12 +22,7 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.wasm.MemoryOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* WasmInstruction for a function call.
|
||||
|
@ -26,7 +26,6 @@ import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* WasmInstruction for a function call.
|
||||
@ -96,14 +95,9 @@ class WasmCallVirtualInstruction extends WasmCallIndirectInstruction {
|
||||
// duplicate this on the stack
|
||||
writer.writeLocal( VariableOperator.get, getVariableIndexOfThis() );
|
||||
|
||||
writer.writeConst( virtualFunctionIdx * 4, ValueType.i32 );
|
||||
writer.writeFunctionCall( options.getCallVirtual() );
|
||||
StructType type = getThisType();
|
||||
if( options.useGC() ) {
|
||||
writer.writeStructOperator( StructOperator.GET, type, new NamedStorageType( type, "", "vtable" ), 0 ); // vtable is ever on position 0
|
||||
} else {
|
||||
writer.writeConst( 0, ValueType.i32 ); // vtable is ever on position 0
|
||||
writer.writeFunctionCall( WasmCodeBuilder.GET_I32 );
|
||||
}
|
||||
writer.writeMemoryOperator( MemoryOperator.load, ValueType.i32, virtualFunctionIdx * 4, 2 );
|
||||
writer.writeVirtualFunctionCall( getFunctionName(), type );
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueTypeParser;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Base class for Code Building.
|
||||
@ -517,6 +516,7 @@ public abstract class WasmCodeBuilder {
|
||||
*/
|
||||
protected void addCallVirtualInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
|
||||
addCallIndirectInstruction( new WasmCallVirtualInstruction( name, javaCodePos, lineNumber, types, options ) );
|
||||
options.getCallVirtual(); // mark the function as needed
|
||||
}
|
||||
|
||||
/**
|
||||
@ -629,7 +629,7 @@ public abstract class WasmCodeBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an array operation to the instruction list as marker on the code position.
|
||||
* Add a struct/object operation to the instruction list.
|
||||
*
|
||||
* @param op
|
||||
* the operation
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package de.inetsoftware.jwebassembly.wasm;
|
||||
package de.inetsoftware.jwebassembly.module;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -33,13 +33,13 @@ import de.inetsoftware.jwebassembly.module.TypeManager;
|
||||
*/
|
||||
public class WasmOptions {
|
||||
|
||||
public final FunctionManager functions = new FunctionManager();
|
||||
final FunctionManager functions = new FunctionManager();
|
||||
|
||||
public final TypeManager types = new TypeManager( this );
|
||||
final TypeManager types = new TypeManager( this );
|
||||
|
||||
public final StringManager strings = new StringManager( this );
|
||||
final StringManager strings = new StringManager( this );
|
||||
|
||||
public final CodeOptimizer optimizer = new CodeOptimizer();
|
||||
final CodeOptimizer optimizer = new CodeOptimizer();
|
||||
|
||||
private final boolean debugNames;
|
||||
|
||||
@ -55,6 +55,9 @@ public class WasmOptions {
|
||||
*/
|
||||
public FunctionName ref_eq;
|
||||
|
||||
|
||||
private FunctionName callVirtual;
|
||||
|
||||
/**
|
||||
* Create a new instance of options
|
||||
*
|
||||
@ -108,4 +111,20 @@ public class WasmOptions {
|
||||
public String getSourceMapBase() {
|
||||
return sourceMapBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FunctionName for a virtual call and mark it as used. The function has 2 parameters (THIS,
|
||||
* virtualfunctionIndex) and returns the index of the function.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Nonnull
|
||||
FunctionName getCallVirtual() {
|
||||
FunctionName name = callVirtual;
|
||||
if( name == null ) {
|
||||
callVirtual = name = types.getCallVirtualGC();
|
||||
functions.markAsNeeded( name );
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.module.WasmOptions;
|
||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||
@ -43,7 +44,6 @@ import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
|
||||
/**
|
||||
* Module Writer for text format with S-expressions.
|
||||
|
@ -28,8 +28,12 @@ import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.module.WasmCodeBuilder;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.MemoryOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
|
||||
@ -246,6 +250,24 @@ public class WatParser extends WasmCodeBuilder {
|
||||
case "i32.load8_u":
|
||||
i = addMemoryInstruction( MemoryOperator.load8_u, ValueType.i32, tokens, i, lineNumber );
|
||||
break;
|
||||
case "struct.get":
|
||||
String typeName = get( tokens, ++i );
|
||||
String fieldName = get( tokens, ++i );
|
||||
NamedStorageType fieldNameType = null;
|
||||
List<NamedStorageType> fields = getTypeManager().valueOf( typeName ).getFields();
|
||||
if( fields != null ) { // field is null on prepare
|
||||
for( NamedStorageType namedStorageType : fields ) {
|
||||
if( namedStorageType.getName().equals( fieldName ) ) {
|
||||
fieldNameType = namedStorageType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( fieldNameType == null ) {
|
||||
fieldNameType = new NamedStorageType( ValueType.anyref, "", fieldName );
|
||||
}
|
||||
addStructInstruction( StructOperator.GET, typeName, fieldNameType, javaCodePos, lineNumber );
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unknown WASM token: " + tok, lineNumber );
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import org.junit.Test;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.binary.BinaryModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.text.TextModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.wasm.WasmOptions;
|
||||
import de.inetsoftware.jwebassembly.watparser.WatParser;
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user