Write the real type of StructType instead anytype

This commit is contained in:
Volker Berlin 2019-01-11 22:21:59 +01:00
parent d2683a32d7
commit 9ac92316f6
10 changed files with 125 additions and 54 deletions

View File

@ -63,7 +63,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
private Map<String, Function> functions = new LinkedHashMap<>(); private Map<String, Function> functions = new LinkedHashMap<>();
private List<ValueType> locals = new ArrayList<>(); private List<StorageType> locals = new ArrayList<>();
private Map<String, Global> globals = new LinkedHashMap<>(); private Map<String, Global> globals = new LinkedHashMap<>();
@ -73,7 +73,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
private Function function; private Function function;
private FunctionType functionType; private FunctionTypeEntry functionType;
/** /**
* Create new instance. * Create new instance.
@ -233,7 +233,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
@Override @Override
protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException { protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException {
int typeId = functionTypes.size(); int typeId = functionTypes.size();
functionTypes.add( new StructType( fields ) ); functionTypes.add( new StructTypeEntry( fields ) );
return typeId; return typeId;
} }
@ -245,7 +245,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
ImportFunction importFunction; ImportFunction importFunction;
function = importFunction = new ImportFunction(importModule, importName); function = importFunction = new ImportFunction(importModule, importName);
imports.put( name.signatureName, importFunction ); imports.put( name.signatureName, importFunction );
functionType = new FunctionType(); functionType = new FunctionTypeEntry();
} }
/** /**
@ -278,7 +278,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
@Override @Override
protected void writeMethodStart( FunctionName name ) throws IOException { protected void writeMethodStart( FunctionName name ) throws IOException {
function = getFunction( name ); function = getFunction( name );
functionType = new FunctionType(); functionType = new FunctionTypeEntry();
codeStream.reset(); codeStream.reset();
locals.clear(); locals.clear();
} }
@ -287,7 +287,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException { protected void writeMethodParam( String kind, StorageType valueType, @Nullable String name ) throws IOException {
switch( kind ) { switch( kind ) {
case "param": case "param":
functionType.params.add( valueType ); functionType.params.add( valueType );
@ -327,7 +327,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
protected void writeMethodFinish() throws IOException { protected void writeMethodFinish() throws IOException {
WasmOutputStream localsStream = new WasmOutputStream(); WasmOutputStream localsStream = new WasmOutputStream();
localsStream.writeVaruint32( locals.size() ); localsStream.writeVaruint32( locals.size() );
for( ValueType valueType : locals ) { for( StorageType valueType : locals ) {
localsStream.writeVaruint32( 1 ); // TODO optimize, write the count of same types. localsStream.writeVaruint32( 1 ); // TODO optimize, write the count of same types.
localsStream.writeValueType( valueType ); localsStream.writeValueType( valueType );
} }

View File

@ -19,6 +19,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.inetsoftware.jwebassembly.wasm.StorageType;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
/** /**
@ -26,11 +27,11 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
* *
* @author Volker Berlin * @author Volker Berlin
*/ */
class FunctionType extends TypeEntry { class FunctionTypeEntry extends TypeEntry {
final List<ValueType> params = new ArrayList<>(); final List<StorageType> params = new ArrayList<>();
final List<ValueType> results = new ArrayList<>(); final List<StorageType> results = new ArrayList<>();
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -46,11 +47,11 @@ class FunctionType extends TypeEntry {
@Override @Override
void writeSectionEntryDetails( WasmOutputStream stream ) throws IOException { void writeSectionEntryDetails( WasmOutputStream stream ) throws IOException {
stream.writeVaruint32( this.params.size() ); stream.writeVaruint32( this.params.size() );
for( ValueType valueType : this.params ) { for( StorageType valueType : this.params ) {
stream.writeValueType( valueType ); stream.writeValueType( valueType );
} }
stream.writeVaruint32( this.results.size() ); stream.writeVaruint32( this.results.size() );
for( ValueType valueType : this.results ) { for( StorageType valueType : this.results ) {
stream.writeValueType( valueType ); stream.writeValueType( valueType );
} }
} }
@ -74,7 +75,7 @@ class FunctionType extends TypeEntry {
if( obj == null || obj.getClass() != getClass() ) { if( obj == null || obj.getClass() != getClass() ) {
return false; return false;
} }
FunctionType type = (FunctionType)obj; FunctionTypeEntry type = (FunctionTypeEntry)obj;
return params.equals( type.params ) && results.equals( type.results ); return params.equals( type.params ) && results.equals( type.results );
} }
} }

View File

@ -26,7 +26,7 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
* *
* @author Volker Berlin * @author Volker Berlin
*/ */
class StructType extends TypeEntry { class StructTypeEntry extends TypeEntry {
private final List<NamedStorageType> fields; private final List<NamedStorageType> fields;
@ -36,7 +36,7 @@ class StructType extends TypeEntry {
* @param fields * @param fields
* the fields of the struct * the fields of the struct
*/ */
StructType( List<NamedStorageType> fields ) { StructTypeEntry( List<NamedStorageType> fields ) {
this.fields = fields; this.fields = fields;
} }
@ -79,7 +79,7 @@ class StructType extends TypeEntry {
if( obj == null || obj.getClass() != getClass() ) { if( obj == null || obj.getClass() != getClass() ) {
return false; return false;
} }
StructType type = (StructType)obj; StructTypeEntry type = (StructTypeEntry)obj;
return fields.equals( type.fields ); return fields.equals( type.fields );
} }
} }

View File

@ -151,8 +151,23 @@ public class ModuleGenerator {
String name = instruction.getTypeName(); String name = instruction.getTypeName();
if( name != null ) { if( name != null ) {
StructType type = types.valueOf( name ); StructType type = types.valueOf( name );
if( type.getCode() == Integer.MIN_VALUE ) { instruction.setType( type );
String className = name; if( type.getCode() == Integer.MAX_VALUE ) {
writeStructType( type );
}
}
}
/**
* Write the struct type
*
* @param type
* the type
* @throws IOException
* if any I/O error occur
*/
private void writeStructType( StructType type ) throws IOException {
String className = type.getName();
InputStream stream = libraries.getResourceAsStream( className + ".class" ); InputStream stream = libraries.getResourceAsStream( className + ".class" );
if( stream == null ) { if( stream == null ) {
throw new WasmException( "Missing class: " + className, -1 ); throw new WasmException( "Missing class: " + className, -1 );
@ -164,13 +179,15 @@ public class ModuleGenerator {
if( field.isStatic() ) { if( field.isStatic() ) {
continue; continue;
} }
StorageType fieldtype = new ValueTypeParser( field.getType() ).next(); StorageType fieldtype = new ValueTypeParser( field.getType(), types ).next();
list.add( new NamedStorageType( fieldtype, field.getName() ) ); list.add( new NamedStorageType( fieldtype, field.getName() ) );
} }
int id = writer.writeStruct( className, list ); int id = writer.writeStruct( className, list );
types.useType( type, id ); types.useType( type, id );
for( NamedStorageType namedType : list ) {
if( namedType.type.getCode() == Integer.MAX_VALUE ) {
writeStructType( (StructType)namedType.type );
} }
instruction.setType( type );
} }
} }
@ -338,7 +355,7 @@ public class ModuleGenerator {
writer.writeMethodParam( "param", ValueType.anyref, "this" ); writer.writeMethodParam( "param", ValueType.anyref, "this" );
} }
ValueTypeParser parser = new ValueTypeParser( signature ); ValueTypeParser parser = new ValueTypeParser( signature );
ValueType type; StorageType type;
for( String kind : new String[] {"param","result"}) { for( String kind : new String[] {"param","result"}) {
while( (type = parser.next()) != null ) { while( (type = parser.next()) != null ) {
String paramName = null; String paramName = null;

View File

@ -107,7 +107,7 @@ public abstract class ModuleWriter implements Closeable {
* @throws IOException * @throws IOException
* if any I/O error occur * if any I/O error occur
*/ */
protected abstract void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException; protected abstract void writeMethodParam( String kind, StorageType valueType, @Nullable String name ) throws IOException;
/** /**
* Finish the function parameter. * Finish the function parameter.

View File

@ -29,7 +29,7 @@ import de.inetsoftware.jwebassembly.wasm.StorageType;
* *
* @author Volker Berlin * @author Volker Berlin
*/ */
class TypeManager { public class TypeManager {
private final Map<String, StructType> map = new LinkedHashMap<>(); private final Map<String, StructType> map = new LinkedHashMap<>();
@ -62,10 +62,10 @@ class TypeManager {
* the type name * the type name
* @return the struct type * @return the struct type
*/ */
StructType valueOf( String name ) { public StructType valueOf( String name ) {
StructType type = map.get( name ); StructType type = map.get( name );
if( type == null ) { if( type == null ) {
type = new StructType(); type = new StructType( name );
map.put( name, type ); map.put( name, type );
} }
return type; return type;
@ -78,7 +78,19 @@ class TypeManager {
*/ */
static class StructType implements StorageType { static class StructType implements StorageType {
private int code = Integer.MIN_VALUE; private final String name;
private int code = Integer.MAX_VALUE;
/**
* Create a reference to type
*
* @param name
* the Java class name
*/
StructType( String name ) {
this.name = name;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -87,5 +99,21 @@ class TypeManager {
public int getCode() { public int getCode() {
return code; return code;
} }
/**
* Get the name of the Java type
* @return the name
*/
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "$" + name;
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018 Volker Berlin (i-net software) Copyright 2018 - 2019 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -108,9 +108,9 @@ class WasmCallInstruction extends WasmInstruction {
while( parser.next() != null ) { while( parser.next() != null ) {
paramCount++; paramCount++;
} }
valueType = parser.next(); valueType = (ValueType)parser.next();
ValueType type; ValueType type;
while( (type = parser.next()) != null ) { while( (type = (ValueType)parser.next()) != null ) {
valueType = type; valueType = type;
paramCount--; paramCount--;
} }

View File

@ -100,7 +100,14 @@ public class TextModuleWriter extends ModuleWriter {
if( debugNames && field.name != null ) { if( debugNames && field.name != null ) {
output.append( " $" ).append( field.name ); output.append( " $" ).append( field.name );
} }
output.append( " (mut " ).append( field.type.toString() ).append( "))" ); output.append( " (mut " );
StorageType type = field.type;
if( type.getCode() < 0 ) {
output.append( type.toString() );
} else {
output.append( "(ref " ).append( type.toString() ).append( ')' );
}
output.append( "))" );
} }
inset--; inset--;
newline( output ); newline( output );
@ -145,7 +152,7 @@ public class TextModuleWriter extends ModuleWriter {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException { protected void writeMethodParam( String kind, StorageType valueType, @Nullable String name ) throws IOException {
methodOutput.append( " (" ).append( kind ); methodOutput.append( " (" ).append( kind );
if( debugNames && name != null ) { if( debugNames && name != null ) {
methodOutput.append( " $" ).append( name ); methodOutput.append( " $" ).append( name );

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2017 - 2018 Volker Berlin (i-net software) * Copyright 2017 - 2019 Volker Berlin (i-net software)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -61,7 +61,7 @@ public enum ValueType implements StorageType {
* @return the value type * @return the value type
*/ */
public static ValueType getValueType( String javaSignature ) { public static ValueType getValueType( String javaSignature ) {
return new ValueTypeParser( javaSignature ).next(); return (ValueType)new ValueTypeParser( javaSignature ).next();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018 Volker Berlin (i-net software) * Copyright 2018 - 2019 Volker Berlin (i-net software)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package de.inetsoftware.jwebassembly.wasm; package de.inetsoftware.jwebassembly.wasm;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager;
/** /**
* Parser for a Java signature. This can be a method signature or a signature of a field. * Parser for a Java signature. This can be a method signature or a signature of a field.
@ -27,14 +28,29 @@ public class ValueTypeParser {
private int idx; private int idx;
private TypeManager types;
/** /**
* Create a new parser. * Create a new parser.
* *
* @param javaSignature * @param javaSignature
* the Jav signature * the Java signature
*/ */
public ValueTypeParser( String javaSignature ) { public ValueTypeParser( String javaSignature ) {
sig = javaSignature; this( javaSignature, null );
}
/**
* Create a new parser.
*
* @param javaSignature
* the Java signature
* @param types
* the optional type manager
*/
public ValueTypeParser( String javaSignature, TypeManager types ) {
this.sig = javaSignature;
this.types = types;
if( javaSignature.startsWith( "(" ) ) { if( javaSignature.startsWith( "(" ) ) {
idx++; idx++;
} }
@ -45,7 +61,7 @@ public class ValueTypeParser {
* *
* @return next type or null * @return next type or null
*/ */
public ValueType next() { public StorageType next() {
if( idx >= sig.length() ) { if( idx >= sig.length() ) {
return null; return null;
} }
@ -56,8 +72,10 @@ public class ValueTypeParser {
next(); next();
return ValueType.anyref; return ValueType.anyref;
case 'L': case 'L':
idx = sig.indexOf( ';', idx ) + 1; int idx2 = sig.indexOf( ';', idx );
return ValueType.anyref; String name = sig.substring( idx, idx2 );
idx = idx2 + 1;
return types == null ? ValueType.anyref : types.valueOf( name );
case 'Z': // boolean case 'Z': // boolean
case 'B': // byte case 'B': // byte
case 'C': // char case 'C': // char